A remarkable late turnaround saw Spain top Group B after they drew 2-2 with Morocco in Kaliningrad on Monday night.
Iran's last-minute leveller against Portugal, paired with Iago Aspas' stoppage-time equaliser for Spain, helped by VAR, mean Spain will now play hosts Russia in the last 16 on Sunday, while Portugal face Uruguay on Saturday in Sochi.
Khalid Boutaib put Morocco ahead early on (14), finishing low after a mix-up on halfway from Spain, but Isco equalised (19) following a classic Spain move.
Spain: De Gea (6), Carvajal (6), Pique (5), Ramos (5), Jordi Alba (5), Busquets (6), Thiago (6), Silva (6), Iniesta (7), Isco (7), Costa (5)
Subs: Aspas (7), Asensio (6), Rodrigo (NA)
Morocco: El Kajoui (6), Hakimi (7), Da Costa (6), Saiss (7), Ziyach (7), El Ahmadi (6), Belhanda (6), Boutaib (7), Boussoufa (6), Amrabat (7), Dirar (7)
Subs: Fajr (7), En Nesyri (7), Bouhaddouz (NA)
Man of the match: Nordin Amrabat
With just nine minutes remaining, substitute Youssef En Nesyri rose highest to head home a corner, but in stoppage time Aspas' superb flick finish found the far corner, despite initially being ruled out for offside, before Iran equalised against Portugal moments later.
There was controversy early on as Gerard Pique's two-footed challenge on Boutaib went unpunished, but Morocco took the lead after a mix-up at the back between Andres Iniesta and Sergio Ramos, allowing Boutaib to race through on goal and slot under David de Gea.
Spain showed their quality five minutes later to equalise as Isco finished off a superb team move from close range, created by Iniesta at the byline.
Boutaib was allowed through on goal shortly after, but this time De Gea stood tall to block from eight yards, while at the other end Sergio Busquets sent an unmarked header from a corner over the bar.
Fernando Hierro made one change to his Spain line-up, bringing in Bayern Munich midfielder Thiago Alcantara for Lucas Vazquez. Morocco have also made just one change, bringing in Wolves defender Romain Saiss for Mehdi Benatia.
Nordin Amrabat came within inches of a goal-of-the-tournament contender as his effort from 25-yards crashed off the bar, while at the other end Isco's header back across goal was cleared off the line by Romain Saiss.
With Spain in second place and Portugal winning against Iran, En Nesyri further compounded Spain's misery and looked to be ending their 22-game unbeaten run after a superb header from Faycal Fajr's corner.
But in stoppage time, Aspas' flick from Dani Carvajal's right-wing cross found the net, and after deliberation with the VAR, the goal was correctly awarded with the former Liverpool man just onside.
Iran then equalised to complete the most unlikely of turnarounds, giving Spain a clash with the hosts, avoiding Uruguay, who have won all three group games without conceding.
Man of the match - Nordin Amrabat
Though he stuck in a few nasty fouls, Amrabat harried the Spain midfield and front line from minute one to 90. He could have shared MOTM with five of his team-mates, but the former Watford man just stood out, and could have gone down in history had his superb long-range effort been two inches lower.
Spain manager Fernando Hierro: "Obviously we can improve, there are things that definitely need to be worked on, and we will definitely be self-critical. Five goals in three matches is not the way forward, I've told the players that. But they are professionals and understand."
Morocco manager Herve Renard: "We would have loved to beat Spain. We should be proud of what we've done, of the team and proud of the Moroccan public too. We've shown we were able to take on two of the best teams in the world in Spain and Portugal."
- Spain remain unbeaten in 23 matches (W15 D8) since losing to Italy at Euro 2016.
- Spain have failed to win their final group game of a World Cup tournament for the first time since 1982, having won each of the previous eight such games before today.
- Morocco have now won just one of their last 10 World Cup matches (D2 L7).
- Sergio Ramos made his 16th appearance for Spain at the World Cup in this game, overtaking Xavi as their most capped outfielder in the competition.
Spain now face Russia in the last 16 on Sunday in Moscow at 3pm.