Increasingly, software needs to dynamically adapt its behavior at run-time in response to changing conditions in the supporting computing infrastructure and in the surrounding physical environment. Adaptability is emerging as a necessary underlying capability, particularly for highly dynamic systems such as context-aware or ubiquitous systems. These systems have reached a level of complexity where the human effort required to get the systems up and running and keeping them operational is getting out of hand. By automating tasks such as installation, adaptation, or healing, Autonomic Computing envisions computing environments that evolve without the need for human intervention. Even though there is a fair amount of work on architectures and their theoretical design, Autonomic Computing was criticised as being a “hype topic” because very little of it has been fully implemented. Furthermore, given that the autonomic system must change states at runtime and that some of those states may emerge and are much less deterministic, there is a great challenge to provide new guidelines, techniques and tools to help autonomic system development. This thesis shows that building up on the central ideas of Model Driven Development (Models as first-order citizens) and Software Product Lines (Variability Management) can play a significant role as we move towards implementing the key self-management properties associated with autonomic computing. The presented approach encompass systems that are capable of modifying their own behavior with respect to changes in their operating environment, by using variability models as if they were the policies that drive the system’s autonomic reconfiguration at runtime. Under a set of reconfiguration commands, the components that make up the architecture dynamically cooperate to change the configuration of the architecture to a new configuration. This work also provides the implementation of a Model-Based Reconfiguration Engine (MoRE) to blend the above ideas. Given a context event, MoRE queries the variability models to determine how the system should evolve, and then it provides the mechanisms for modifying the system architecture accordingly. The presented work has been validated from three different perspectives: (1) Scalability of the approach, (2) reliability-based risk of run-time reconfigurations and (3) degree of autonomic behavior achieved. This evaluation was performed with the participation of human subjects by means of a Smart Hotel case study which was deployed with real devices. Experimentation shows that our approach achieves satisfactory results with regard to scalability and reliability-based risk; nevertheless, we found some scenarios which required a greater level of detail to define the autonomic behaviour since these scenarios deal more directly with user preferences and tastes. However, even though this lack of coverage could be complemented by the development of specific components for the unsupported cases, it does not seem economically realistic to build individual features to suit each user. Our intent is to focus on commonalities and abstractions that are valid across a set of users, looking for a trade-off between personalization and reusability.