The Londoners had four great chances to take the lead inside the first quarter of an hour, but had to wait until the second half to break the deadlock.
Mark Beevers opened the scoring as he headed in a corner from eight yards.
Vale's Enoch Andoh had chances to score either side of Beevers' goal before Lee Gregory hit a stoppage time penalty after he was fouled by Jak Alnwick.
Millwall moved up to 12th in League One after an impressive third away win of the season at Port Vale.