Héctor Herrera put the Portuguese team ahead, before Timo Werner came off the bench at the break and immediately brought Leipzig level.
The German side were vulnerable defending set pieces though, and they concede again from one to Danilo, who put Porto back ahead, before Maxi Pereira wrapped up the win in stoppage time.
Herrera punishes poor Leipzig defending
Hosts Porto, beaten 3-2 by Leipzig in Germany two weeks ago, named an unchanged line-up from their 3-0 league win against Boavista at the weekend. Leipzig themselves, bruised from back-to-back domestic defeats to Bayern Munich, made four changes, including surprisingly leaving out both Yussuf Poulsen and Werner. Bernardo, Kevin Kampl, Bruma and Jean-Kévin Augustin were the men to come in.
Porto were to have the better of the early exchanges, but despite losing Moussa Marega early to a hamstring injury, they took the lead soon after he came off. Leipzig dealt poorly with a Porto corner – Herrera headed down towards Danilo, his shot was blocked, it somehow fell back to Herrera and he managed to strike in through the hands of Peter Gulácsi.
There could have gone further ahead five minutes later. Vincent Aboubakar manged to get past Dayot Upamecano and get the ball over a grounded Gulácsi to find André André, who had come on for Marega. He though wasted the opportunity, firing it over.
Leipzig looked uncertain at the back, although they did respond reasonably well going forward after going behind. A free-kick from Emil Forsberg was an awkward one for goalkeeper José Sá, who’s keeping Iker Casillas out of the side, but he was able to put it wide. Forsberg also had the ball in the net after being found by Augustin, but the Porto defence had already seen the flag up for offside against Augustin.
Werner cracker ultimately proves in vain
Ralph Hasenhüttl unsurprisingly turned to Werner, as well as Lukas Klostermann, for the second half, and the striker had his side level within minutes. From the counter, Marcel Sabitzer played him through, onside, and Werner placed the ball into the top corner, his first goal in the Champions League.
The Portuguese side were rocked by that goal, but soon went about trying to get back ahead. Aboubaker’s shot went over moments after Porto thought they should have had a penalty for a Willi Orban handball – there hadn’t been much he could have done about it though.
Danilo then headed over, a minute before another chance came to him. A free-kick from Alex Telles was perfectly placed, but the Leipzig defence was caught napping as Danilo was one of several players to charge forward, winning the header to put his side back in front.
Leipzig did what they could to try to get level, but their finishing was lacking. Sabitzer fired wide and then over, after Porto failed to clear a corner. Klostermann also had a shot go over the bar, but they couldn't fine anymore of the magic that Werner had provided earlier in the half.
The final act came in stoppage time. On the halfway line, Vincent Aboubakar set up a ball for substitute Pereira to run on to. He took it all the way, before turning the ball around Gulácsi, a rare goal for the Uruguayan defender which sparked crazy scenes on the pitch. That made the game save, and Porto leapfrog Leipzig in the Group G table.