Southampton would be left to rue missed opportunities throughout and found themselves on the back foot when Jack Stephens — unfortunately — turned Tanguy Ndombele’s attempt into his own net on 10 minutes.
Danny Ings nearly made an immediate response only to turn his shot from off the crossbar, before Ryan Bertrand and Nathan Redmond both came close to an equaliser.
Shane Long was then left with a simple tap in to draw Saints level after Redmond saw his initial attempt saved.
Southampton was forced into a change with five minutes to go in the first half when James Ward-Prowse went down under a combination of a non contact injury and an inadvertent collision with Ryan Sessegnon. The midfielder was stretchered off.
The second half came to life when Ings was finally rewarded with a goal to put Saints ahead 2-1 in the 72nd minute, but the lead was short-lived as Lucas found the net just six minutes later.
Redmond took on the entire Spurs defence with a meandering run that freed Ings to curl a right-footed shot past Lloris and give Saints a 2-1 lead on 72 minutes.
Son then won his penalty after Angus Gunn was caught in no-man’s land and brought the forward down three minutes from full-time.
Gunn guessed right but the South Korean international fired past the goalkeeper to confirm Spurs’ place against Norwich City.
Tottenham: Lloris, Vertonghen (Fernandes (54), Aldeweireld, Tanganga, Sessegnon (Sanchez 90), Winks, Dier, Ndombele (Alli 61), Aurier, Son, Lucas
Unused subs: Gazzaniga (GK), Sanchez, Skipp, Parrott, Cirkin
Goals: Stephens (OG 12), Lucas (78), Son (PEN 87)
Bookings: Fenandes (59)
Southampton: Gunn, Bertrand, Bednarek, Stephens, Ward-Prowse (Vestergaard 40), Redmond, Hojbjerg, Romeu, Boufal (Armstrong 67), Long (Adams 82), Ings
Unused subs: Lewis (GK), Adams, Armstrong, Smallbone, Vokins, Obafemi
Goals: Long (34), Ings (72)
Bookings: Bednarek (55), Romeu (84), Adams (85), Gunn (86)