The home side, playing at the stadium which will host the May 19 final, got the better of the first half with a Franck Ribery goal, although Real fought back in the second-half as Mesut Ozil equalised in his homeland.
But half-Spanish Germany forward Gomez, who had missed a host of chances, poached a 90th-minute winner, while the dying seconds marred by a scuffle following a wild kick from Marcelo on Thomas Mueller, for which the Brazilian was lucky to escape with just a booking.
Bayern will also claim they had three good penalty appeals rejected, but replays showed that Howard Webb probably made the right decisions, with Ribery clearly diving for one, the ball striking Pepe’s chest for another and - just before the winner - Sergio Ramos appearing to get the ball as he slid in on Gomez.
It was a cracking spectacle for the neutral as two of Europe's traditional heavyweights did battle in Germany.
Bayern had a gameplan to frustrate Real and, with the visitors strangely one-dimensional in attack, it paid off in the first half.
The Spaniards actually started the game brighter, dominating possession as Bayern sat deep - the stubborn hosts largely frustrated them, although Karim Benzema did force a decent save from Manuel Neuer on seven minutes.
After initially struggling to keep the ball past halfway, Bayern sprung into action on the quarter-hour mark as Ribery wriggled into the box before diving over a challenge from Sergio Ramos.
It was a clear act of simulation - Ramos had pulled away from the tackle - but the perceived injustice spurred on the Frenchman: it was he who rifled home a low drive after Ramos failed to clear a corner soon afterwards.
Real tried to take the game to the hosts, which merely allowed them to pick the visitors off on the break. Bastian Schweinsteiger drilled a low shot just wide, while Iker Casillas denied Gomez a spectacular finish after Real were again caught napping by the counter attack.
The visitors, meanwhile, were restricted to long-range efforts from Angel Di Maria and Cristiano Ronaldo, hemmed back at times by rampaging young left-back David Alaba and, on the other flank, let down by continued poor positional play from Real counterpart Fabio Coentrao.
The second half had a slightly different balance, as Real started in more direct fashion - and they quickly drew level, although it was a comical goal by both teams’ standards.
Benzema had initially sent Ronaldo clean through with a superb through-ball, only for the Portuguese star to fire straight at Neuer, a poor finish from a man who has scored more than 50 goals this season.
But the ball was still alive as Bayern struggled to clear their lines, failing to intercept a weak attempt at a shot from Benzema. The ball drifted through to Ronaldo, who cut the ball back for Ozil to tap in from two yards.
With Real claiming an away goal, the onus was now on Bayern to attack, which they did, although Gomez - in brilliant form this season - was unable to take a trio of chances before his final act.
Casillas was forced into a speedy and brave save at the feet of Gomez after Philipp Lahm sent him scuttling through, while the former Stuttgart striker headed over from a cross by the Germany right-back.
Those opportunities sandwiched a bad miss from the Germany hit-man when - after another missed header by the increasingly flaky Ramos - he toe-poked over the bar from close range under pressure from the Spain defender.
A scrappy spell ensued as an already feisty match threatened to boil over, with a rash of bookings for both sides and a terrible tackle from Ramos on poor Mueller, punished by a yellow that could easily have been red.
There was a late surge from both sides as Bayern had a weak penalty appeal rightly ignored when Ribery’s dribble and cut-back saw the ball ricochet into Pepe’s chest, while Real countered but were foiled when Benzema’s shot was blocked.
Bayern piled on the pressure in the latter stages, with Gomez unable to head Lahm’s cross over before having probably the strongest penalty appeal waved away when he raced through only to go down under a desperate slide tackle from Ramos. Replays were inconclusive but appeared to show Ramos taking the ball, although the liability that is Coentrao may well have got a chunk of the player after the ball had gone.
Gomez was not to be denied though, helped by more weak defending by Coentrao, who let Lahm zip past him into a free right wing: the cross was low and vicious, and Gomez somewhat fortunate to bundle it home, but it was a triumph for persistence, the 40-goal striker refusing to give up despite his prior frustration.
That came in the last minute of normal time and there was more drama to follow when in the third minute off added time Marcelo hacked out at Mueller, who had drawn three assaults in his half-hour cameo. All hell broke loose, and Marcelo appeared to raise an arm on Jerome Boateng.
Bayern’s complaints at the lack of a red card, however, were tempered by the knowledge that Real have to win at the Bernabeu to set up their dream Clasico final.
- Related links