TCP is said to be reliable because when an application receives data, it knows that this is exactly the data that the sender sent. No part of the data was lost, reordered, etc.
Error control is the part of TCP that deals with ensuring the reliability of connections. For example, if the sender sends two packets A and B and the receiver received only B, the TCP implementation on the receiver side will wait a little in case A took longer than B to arrive. If A finally arrives, the receiver will release A to the application before B. If A doesn’t arrive after a while, the receiver will transmit a request to the sender to retransmit A. (I am simplifying somewhat, see the specification for details.)
This is not related to congestion and flow control. They help the performance of the network, but they aren’t needed or helpful to make a connection reliable.