Every multiplayer FPS game has lag compensation and client prediction, although whether you'd consider it to be "heavy" in Battlefield 3 is somewhat subjective. People complain about it, especially in the more "realistic" shooters, but we really generally have no idea how it was implemented or how good or bad it is in a given game.
The reason why it tends to be so much worse in games like BF3 and MW3 comes down to the amount of time it takes to score a kill. In a "non-realistic" FPS such as TF2 or Halo, the amount of time it takes to kill another player can be generally measured in seconds. The heavy's minigun spins up, and fires on another heavy, and a couple of seconds later (assuming he has no medic) the enemy heavy will be dead. A difference of 50 milliseconds or so generally makes very little difference.
However, in a "realistic" shooter, the time to score a kill can be measured in milliseconds. Take the G36C in BF3, for example. It can fire at 750 RPM, and does 25 damage per shot at short range. If your health is at 100, that means it kills in 4 shots. This takes a total of 320 milliseconds. In Modern Warfare 3, there are some guns that kill in less than 150 milliseconds.
With a dedicated server architecture (like many PC games have, but few console games have), it's generally possible for you to select a server and know ahead of time what your average ping/latency are before you start playing. This generally means that you and everyone else on the server are experiencing similar latency.
In a system where you can't choose the server (or the architecture is peer-to-peer) there's a greater chance that the latency of the various clients will be uneven. In a peer-to-peer scenario (which the CoD franchise uses almost exclusively on consoles) there is always one player who is hosting the game, and he experiences minimal latency compared to every other client. Since the game is trusting one of the peers to host, there's also a chance that that peer could be tampering with the system to gain an advantage.
If the difference between your latency and your enemy's latency is 100 milliseconds, this could cause serious differences in your experiences. Even if you were 80 milliseconds faster to start firing on him, it might not matter. The latency compensation measures might be working in your favor or against you. 80 milliseconds is an extraordinarily small amount of time in the scope of human reaction time.
So then, is the issue bad network code or are you being punished because of your (good/bad) connection? In reality, it's a feature of the game. The people who design and write these games are well aware of the limitations of current network architecture. They choose to make a fast paced game that is frequently unfair because we will buy it and play it. Until we're all connected via zero latency links to one another, or we decide that we don't really like games where a kill takes tenths of a second, we're going to have to deal with this frustration.
In the meantime, try to reduce the amount of traffic on your network while you play. This can help smooth out latency variances that can cause issues. If you have the choice of servers, pick ones that are as low "ping" as possible, but remember that latency isn't everything.
I find that removing the latency deltas from the equation helps the most though. Try to surprise enemy players, or find another way to gain an advantage that gives you a few more hundreds of milliseconds to react. And remember that sometimes, the game's not going to treat you fairly.