The young attacker, 19, curled a shot into the corner with 16 minutes left to lead his side to their fourth consecutive cup final.
BVB were beaten 4-1 by their arch-rivals in the Bundesliga at the start of April, but Thomas Tuchel was confident in his pre-match media conference they would do better this time around.
Things indeed did go Dortmund's way early on when Marco Reus scored after some poor play from Javi Martinez, only for the Spaniard to quickly make amends when he equalised after a corner.
Mats Hummels then gave Bayern the lead shortly before the break, but Dortmund refused to give up and Pierre-Emerick Aubameyang levelled halfway through the second half, before Dembele netted the winner.
Wednesday's defeat means Bayern are now on a five-game winless streak in all competitions that also saw them exit the Champions League, while Dortmund are on track to win their fourth DFB-Pokal, having lost the final in each of the last three seasons, the last one against their bitter rivals.
There were chances for both sides in the opening stages, with Aubameyang wasteful early on before Franck Ribery was denied by goalkeeper Roman Burki minutes later.
BVB broke the deadlock when Reus found the net in the 19th minute after some sloppy play from Martinez, who saw his poor backpass intercepted by Raphael Guerreiro. Goalkeeper Sven Ulreich managed to divert the Portugal international’s shot on to the upright, but Reus beat Philipp Lahm to the rebound and tapped home with ease.
Martinez quickly made amends, though, as the Spaniard restored parity again in the 28th minute, beating Burki with a powerful header after Xabi Alonso's corner from the right.
The former Athletic Bilbao man seemed determined to single-handedly turn things around after his earlier mistake and he was unfortunate not to put Bayern ahead when he hit the upright with yet another header after a corner.
There was no denying the home side in the 41st minute, however, as Hummels found the net with a clinical finish after some good work from Ribery down the left wing.
Robert Lewandowski should perhaps have made it 3-1 in the dying seconds of the first half when sent clean through on goal by Arturo Vidal, but Burki proved to be too much of an obstacle.
Bayern continued to push for a third and Arjen Robben wasted another gilt-edged chance to seal the win minutes later, firing a shot against the post via Sven Bender after some clumsy play from Burki leading up to the chance.
And Bayern were made to pay for their profligacy in the 69th minute when Aubameyang levelled, directing a header past Ulreich at the far post after a sublime cross from Dembele.
There was still more to come from Dembele as the Frenchman fired BVB into the lead, finding the top corner following a rapid break after Lahm had lost possession in midfield.
Alonso was then booked for simulation as he tried to win a penalty in a desperate attempt to send the game into extra time, before Robben was denied by Burki late on as the visitors held on for a heroic victory.