The game finished 2-2 over 90 minutes as Christian Pulisic’s early goal for Dortmund was cancelled out by Robert Lewandowski.
Pierre-Emerick Aubameyang, last season’s top-scorer in the Bundesliga, restored Dortmund’s lead with 19 minutes left before Lukasz Piszczek’s late own goal took the match straight to penalties.
“We haven’t had much time to get ready, but now we had a little more time to train and I’m very happy that we won the first title,” said Lewandowski, who drilled home Bayern’s first penalty in the shoot-out.
Ex-Barcelona defender Bartra, the only player badly injured in April’s bomb attack on the Dortmund team bus, saw the 12th spot-kick saved to hand Bayern the cup for the second year running.
Aubameyang, the subject of a big-money offer from China, and Ousmane Dembele, who Barcelona have reportedly tabled a 70 million euros ($82.4m) offer for as Neymar’s replacement, both impressed for Dortmund.
The win gives Bayern their first title of the season as the defending champions open the new Bundesliga season on Friday August 18 at home to Bayer Leverkusen.
The victory offers head coach Carlo Ancelotti a welcome boost after his team lost five of their six previous warm-up games.
“We know the pre-season hasn’t gone the way it should,” said Bayern’s goalkeeper Sven Ulreich, who saved Bartra’s kick.
“Today we saw the real FC Bayern again and we proved we had the morale to come back.”
World Cup-winner Mario Goetze was missing for German Cup winners Dortmund as the 25-year-old dropped out with a back injury after five months missing with a metabolic disorder.
Dortmund’s defender Marc Bartra plays the ball on August 5, 2017
Bayern were missing stars Jerome Boateng, David Alaba and Arjen Robben, while new-signing James Rodriguez is out with a hamstring injury.
Dortmund took the lead after just 12 minutes when Javi Martinez lingered over the ball a fraction too long and was robbed by Pulisic.
The 18-year-old US international sprinted away from the scrambling Munich defence.
He tucked his shot past Sven Ulreich, Bayern’s stand-in goalkeeper with Germany’s shot-stopper Manuel Neuer just back in training after foot surgery, who later saved Bartra’s spot kick.
Bayern drew level on 18 minutes when a super long pass from new-signing Sebastian Rudy found Kimmich, whose cross was buried by Lewandowski at close range.
Bayern could have doubled their lead on 31 minutes when Thomas Mueller’s header forced Roman Burki into a point-blank save.
Rudy’s long-range shot also needed a great save from the Dortmund shot-stopper.
Both sides had their chances after the break, but Dembele’s pass picked out Aubameyang and the Gabon striker showed ice-cold finishing to put Dortmund ahead on 71 minutes.
With time almost up, Rudy rattled the crossbar and Kimmich stabbed the ball home at the second attempt off Piszczek to take the game straight to spot kicks.
Both Bayern’s Kimmich and Dortmund’s Sebastian Rode had their penalties saved in the shoot-out until Bartra’s shot was blocked by Ulreich to send the trophy to Munich.
Download our app and read this and other great stories on the move. Available for Android and iOS.