Gomez took his season tally to a league-leading 15 by scoring in the 13th and 57th minutes, after Christian Gentner had put the home side ahead in the sixth minute.
Christian Molinaro was sent off in the 29th for a bad tackle on Arjen Robben, five minutes after earning his first yellow card for another lunge at the Dutchman.
Gomez should have scored against his former side in the fifth minute, when Robben rounded the keeper before playing it across the empty goal, only for the 26-year-old striker to miss the ball.
Gentner scored 40 seconds later when Martin Harnik nodded down Molinaro’s cross for the midfielder to volley in from 10 meters (yards).
However, Gomez made amends when he got ahead of Molinaro to deflect Rafinha’s cross past the helpless Sven Ulreich.
Ulreich produced a stunning one-handed save to stop Thomas Mueller’s deflected shot in the 25th, and the visitors were given a boost when Molinaro was sent off four minutes later.
Gomez eventually scored the goal which Bayern’s pressure deserved when Philipp Lahm cut the ball back for the striker to drill a shot into the right corner.
Robben twice fired over from a promising positions late in the last 15 minutes.
Cacau almost equalized in the 81st, when he stretched to reach Daniel van Buyten’s header back to Manuel Neuer only for the effort to go agonizingly over.
Bayern is top with 34 points, ahead of Dortmund and Schalke on 31 points, and fourth-place Borussia Moenchengladbach on 30.
Olcay Sahan’s spectacular equalizer for Kaiserslautern at Dortmund earlier Sunday had given Bayern its chance to go three points clear, with fellow challenger Moenchengladbach having lost 1-0 to Augsburg on Saturday.
Sahan struck his first ever Bundesliga goal on the hour mark with a crisp volley over his shoulder and into the right corner, canceling out Shinji Kagawa’s 27th-minute opener and lifting Kaiserslautern out of the relegation zone to 15th.
Dortmund coach Juergen Klopp brought on Mario Goetze six minutes later and the 19-year-old playmaker almost struck the winner in the 82nd with a fierce shot that hit the crossbar. It was the third time Dortmund struck the crossbar or post.
“Kaiserslautern earned their luck,” Klopp said. “If Sahan hadn’t scored the goal of the month then it would have gone very well for us.”
Ilkay Guendogan set up Kagawa to dispatch a shot to the left corner despite being surrounded by Kaiserslautern defenders. The Japan midfielder fired narrowly wide three minutes later.
Robert Lewandowski had earlier grazed the crossbar with a volley, and Mats Hummels went close again before the interval, when Sahan blocked the defender’s header on the line.
Sahan equalized when Lukasz Piszczek failed to clear Christian Tiffert’s hopeful cross, the 24-year-old catching the dropping ball cleanly to give Roman Weidenfeller no chance.
Hummels hit the post with a header from a free kick in the 72nd, seconds before Kevin Trapp saved from Lewandowski in a one on one.
Dortmund kept pushing for the winner, but Goetze—who had been unable to start because of a groin problem—was unlucky to see his dipping effort strike the crossbar.