Bayern's victory lifted them two places in the table to third, but they will drop back to fifth if Eintracht Frankfurt earn a fifth straight win at home to Wolfsburg on Sunday and RB Leipzig beat Moenchengladbach.
Bayern built on their 5-1 mid-week thrashing of Benfica in the Champions League, but still lag well behind Dortmund, who won 2-0 at home against Freiburg.
The last time Bayern were so far behind in the table was in 2010/11, when Dortmund won the title, and their bid for a seventh straight Bundesliga crown is in danger after only their third win in their last nine league games.
Gnabry, who started for Arjen Robben, put Bayern ahead on 20 minutes in Bremen after Joshua Kimmich's chip into the area shortly after the visitors had a penalty appeal turned down.
Thomas Mueller then fired wide with the goal at his mercy, but Bayern's defensive frailties returned to haunt them as Bremen equalised 14 minutes later.
Centre-back Jerome Boateng was out-leapt by Japan forward Yuya Osako after a pin-point accurate cross as Bremen drew level after midfielder Nuri Sahin had gone close.
It was 1-1 at the break, but Bayern grabbed the winner five minutes into the second period when Mueller delayed his pass into the box for Gnabry to deflect the ball into the net.
There was more good news for Bayern coach Niko Kovac.
Winger Kingsley Coman came on for his first appearance since tearing ankle ligaments on the opening day of the season in August.
Likewise, Thiago Alcantara played the last 10 minutes after a month out with injury.