A first half of Porto playing deep to frustrate City was enlivened only by a six minute spell in which both teams scored before normal service was resumed before the hosts almost regained the lead close to the break.
With the first attempt on goal from either side Porto scored first on 14 minutes. City, playing their 78th Champions League game, gave the ball away cheaply and Luis Diaz ran at the home defence who backed off allowing the Colombian to drive home. This was Porto's first goal in England for seven visits.
City now had more urgency in their play and within five minutes were awarded a penalty after Raheem Sterling was brought down by Pepe after a scramble in the penalty area.
The visitors keeper Augustin Marchesin was injured in the build-up and Sergio Aguero had to wait before powerfully hitting the leveller past his Argentine compatriot.
The game then reverted to type with City enjoying plenty of possession but failing the trouble the Porto defence. Then just before the break Kyle Walker came to City's rescue by clearing a deflected Moussa Marega cross off the line.
But Gundogan was not to be denied and after sustained home side pressure his exquisite 65th minute free kick gave City the lead for the first time in the game.
City comfortably played out the remaining minutes and deserved the points following a slow start.
Full Time Group C
Man City: 3 (Aguero pen 20, Gundogan 65, Torres 73)
FC Oporto: 1 (Diaz 14)
Att: Behind closed doors