Holders Bayern Munich beat Eintracht Frankfurt to set up a German Cup final against Bayer Leverkusen.
Ivan Perisic's stooping header was the only goal of a first half the treble chasers entirely dominated.
Eintracht, the 2018 winners, improved after the break and Danny da Costa levelled moments after coming on.
Robert Lewandowski scored the winner from Joshua Kimmich's pass, with a goal initially ruled out for offside but awarded by the video assistant referee.
That is the Pole's 45th goal in only 39 games for Bayern this season.
The final will be in Berlin's Olympic Stadium on 4 July, with Leverkusen beating fourth-tier Saarbrucken 3-0 in the other semi-final.
Bayern, who are two league wins away from an eighth consecutive Bundesliga title, have won 20 of their previous 21 games in all competitions.