Code-reuse attacks continue to pose a significant threat to systems security, from resource-constrained environments to data-centers. While current mitigation techniques excel at providing efficient protection for high-end devices, they typically suffer from significant performance and energy overheads when ported to the embedded domain. Thus, there is a need for developing new defenses that (1) have low overheads, (2) provide high security coverage, and (3) are especially designed for embedded devices. In this paper, we present EPI, an efficient pointer integrity mechanism that is tailored to microcontrollers and embedded devices. EPI assigns unique tags to different application assets, namely return addresses, function pointers, and data pointers to distinguish them from regular data. We then use unique memory instructions for accessing the valuable assets to prevent regular store instructions—as part of a buffer overflow vulnerability for example—from manipulating them. In order to avoid the cost of tagging the entire memory, we propose a 32-bit friendly encoding scheme to inline the tags within the application data. Using simple compiler support and minor hardware changes, we show that EPI mitigates code-reuse attacks, including the recent data-oriented programming ones. For certain modes of operation, namely return address integrity, EPI does not require compiler support, thus is applicable to legacy binaries. Our results show that EPI has 0.88% runtime overheads on the SPEC CPU2017 workloads making it viable for embedded and low-resource systems.