Cristiano Ronaldo scored his 111th international goal for Portugal on Wednesday night, while France and Netherlands dropped points in their qualifiers.
The Republic of Ireland were without a point in Group A heading into their difficult game in the Algarve against Portugal.
Ronaldo was afforded an early chance to give his side the lead as the hosts were awarded a penalty.
However, his penalty – given after a lengthy VAR review – was saved by 19-year-old Portsmouth goalkeeper Gavin Bazunu.
Sheffield United defender John Egan then headed Ireland in front from a corner just before the break to scores his first international goal.
That looked to have been enough to secure the Republic a memorable victory, only for Ronaldo to glance in a header with just one minute left – and then in the fifth minute of stoppage time, the United frontman produced a repeat finish to spark wild celebrations.
The late victory puts Portugal three clear of Serbia at the top of Group A, having played a match more, while Ireland remain pointless.
Luxembourg beat Azerbaijan 2-1 to move a point behind second-placed Serbia
Denmark beat Scotland 2-0 in Copenhagen to maintain their 100 per cent start to Group F.
Daniel Wass headed the Danes in front in the 14th minute and Joakim Maehle swiftly doubled the lead with a close-range finish.
Israel are second after a 4-0 win over the Faroe Islands in Torshavn, where PSV Eindhoven midfielder Eran Zahavi completed a hat-trick in stoppage time.
Austria ran out 2-0 winners away to Moldova, with the kick-off delayed after a drone flew over the stadium in Chisinau.
Christoph Baumgartner broke the deadlock just before the break, with Marko Arnautovic adding a second in stoppage-time to wrap things up as Austria moved level on points with Israel and two clear of Scotland.
France held out with 10 men to draw 1-1 against Bosnia and Herzegovina in Strasbourg to consolidate their position at the top of Group D.
Captain Edin Dzeko fired Bosnia into the lead after 36 minutes, but Les Bleus were soon level when the ball bounced in off the back of Antoine Griezmann’s head.
Six minutes into the second half, Sevilla defender Jules Kounde was shown a red card, upgraded from a caution, for a foul on Arsenal full-back Sead Kolasinac, who was forced off injured.
Earlier, Kazakhstan struck an equaliser deep in stoppage time to draw 2-2 against Ukraine in Astana.
In Group G, substitute Risto Radunovic struck a stoppage-time equaliser as Montenegro fought back to draw 2-2 against leaders Turkey in Istanbul.
Norway and Holland drew 1-1 in Oslo, which leaves the top four teams separated by only a point.
Erling Haaland gave Norway the lead in the 20th minute with a neat turn and finish in the penalty area, with Davy Klaassen hauling the Dutch level before half-time.
Vladislavs Gutkovskis scored twice as Latvia beat Gibraltar 3-1 in Riga to get their first win.
It finished goalless between Group H leaders Croatia and Russia at the Luzhniki Arena in Moscow, while Slovenia fought back to draw 1-1 against Slovakia in Ljubljana.
Cain Attard scored twice as Malta ran out 3-0 winners over Cyprus, who had defender Costas Soteriou sent off just before half-time.