A poor Emre Can giveaway in midfield led to Man City's first goal of the game as Kevin De Bruyne redirected Riyad Mahrez's cross past Marwin Hitz in the Dortmund goal to give his side the lead just before 20 minutes.
Can's rough night looked set to continue when he was whistled for a penalty on City's Rodrigo, but the Germany international was bailed out after a VAR check showed there was a handball before his foul.
Dortmund looked to have drawn level before half-time when Jude Bellingham dispossessed Man City keeper Ederson and was left to tap into an empty net, but the referee harshly whistled the 17-year-old for a foul on the play and Pep Guardiola's team took their one-goal lead into the break.
The visitors faced a tough challenge in the second half as they tried to find a way back into the game against a Man City team that came into the match without conceding a goal in the Champions League for 706 minutes.
Ederson came to City's rescue early in the second half, saving from Erling Haaland with an outstretched foot as the German side continued to cause City problems.
Dortmund did well to keep the deficit to a red-hot City team at a single goal before Marco Reus finished off a nice team move with a slick strike to give his team an important away goal.
However, Foden scored a clever goal from an Ilkay Gundogan assist just before full-time to give Man City the win and an ever-so-slender advantage over Dortmund for the return leg on April 14 in Germany with a spot in the Champions League semifinals on the line.
Guardiola's side lacked their usual sharpness in the final third but the Spaniard said his team had to deal with a huge burden of expectation thanks to their red-hot form coming into the match and Dortmund's struggles in the Bundesliga.
"When you win 26 games in 27 and they are not winning the Bundesliga, the pressure is on our shoulders," he said after the match.
"Everything is guaranteed for us. Everybody believed we would win.
"We had an incredible commitment and desire to go through."
Guardiola said he would look to make some adjustments for the return leg but stressed they would not be going to Germany to sit back and defend.
"I asked the players to win the game. We did it and now we go to Dortmund not to defend," he added. "We'll adjust our pressing, adjust our buildup and play 90 minutes to try and reach the semifinal."
Guardiola hailed the performance of 20-year-old Foden, who looked a real danger towards the end of the contest.
"Phil was brilliant in his aggression in the last 30 minutes, he was our threat," Guardiola said.
"Second half, he played really well, and one against one arriving in the final third, he had two, three chances to score and finally did."
Following the match, Dortmund defender Mats Hummels told DAZN: "It was a very good performances of ours, I think. It's very annoying that firstly we only score one goal from what we created and secondly we conceded a goal which looked like we could defend it. We've thrown everything in today. What we really should do every three days.
"If we go home with a 1-1, everyone's just very pleased. But with that late 2-1 for City, the feeling's not so great now even though we made a lot of things right."
Hummels' manager Edin Terzic added: "Our chances to go through are still there. A 1-1 after 90 minutes would have meant we'd be virtually through at kick off in Dortmund. That's always a good constellation in the knockout stages."