Encapsulation is the process of putting data and code (that operates on data) together in a single unit, which, acts as a protective wrapper for data and code. Access to the data is provided via controlled access (public interface).
Consider an example of a simple wristwatch.
Abstraction means to provide the simplest view of a complex concept (showing only the necessary part). So, in this case, it displays only time.
Encapsulation means not only provide the simplest view of complex concept (Abstraction!) but also hide and protect internal implementation. The end user cannot see how time is being calculated; what gives energy to the wristwatch; how the internal circuits are structured and so on…
The glass and plastic body forms a protective wrapper (Encapsulation) which hides the internal implementation details (hiding the complexity) and shows the current time (…only relevant part, Abstraction!).
Encapsulation gives access to modify the data via the controlled public interface. In this case, it’s a push button which is used to change/set the time.
From this example, it is clear that the two concepts are related. Without proper encapsulation, there would be no abstraction. Encapsulation not only helps a code achieve abstraction (shows only relevant functionality) but goes one step further and hides everything else, which is irrelevant to the user.
In essence, Encapsulation picks up where abstraction leaves off. In code, you will either have both abstraction and encapsulation, or you will have neither.