Blocks are downloaded serially from specific peers, but a node can download blocks from multiple peers at the same time, effectively downloading blocks in parallel. This parallel download involves downloading different blocks from different peers, rather than downloading different parts of the same block from different peers.
This design allows nodes to download the blockchain faster because they are not limited by the upload speed of a single peer. It also adds a layer of redundancy.
Even if blocks are downloaded in parallel, they must be processed sequentially. This is essential for nodes to maintain accurate information about existing, unspent transaction outputs (UTXOs) and to verify the validity of transactions.
The actual implementation of this process in Bitcoin Core is quite complex and involves various aspects such as timeout handling, block validation, etc. You can get a deeper understanding by reviewing the actual code in the Bitcoin Core GitHub repository.
You can also check out the P2P network section of the Bitcoin developer site. See the description of the Block, GetBlocks, GetData, and GetHeaders messages involved when blocks are transferred between nodes.