diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index 97fbed7ff13ef836ad9de9da68f9c5d544050e7d..707ae91f1300ba2db2651d7f3297aa9577cf78bc 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -20,6 +20,15 @@
  * @todo Find a way to disable services which are not used
  */
 class ServicePool {
+	/**
+	 * A counter for messages
+	 *
+	 * Each key-value pair corresponds to one MessageType within a Service. The most significant 8 bits are the number
+	 * of the service, while the least significant 8 bits are the number of the Message.
+	 *
+	 * @todo Update this according to the final number of Services and Messages
+	 */
+	etl::map<uint16_t, uint16_t, 10*20> messageTypeCounter;
 public:
 	RequestVerificationService requestVerification;
 	EventReportService eventReport;
@@ -44,6 +53,18 @@ public:
 	 * Services already stored as values will point to the "new" Services after a reset.
 	 */
 	void reset();
+
+	/**
+	 * Get and increase the "message type counter" for the next message of a type
+	 *
+	 * The message type counter counts the type of generated messages per destination, according to requirement
+	 * 5.4.2.1j. If the value reaches its max, it is wrapped back to 0.
+	 *
+	 * @param serviceType The service type ID
+	 * @param messageType The message type ID
+	 * @return The message type count
+	 */
+	uint16_t getMessageTypeCounter(uint8_t serviceType, uint8_t messageType);
 };
 
 /**
diff --git a/src/Message.cpp b/src/Message.cpp
index efedb65c16b2388fc6a87326cb0ffbcd35f2fac9..7fb5974e00e6f59d8574a72c1aad1126be7cdfc0 100644
--- a/src/Message.cpp
+++ b/src/Message.cpp
@@ -2,6 +2,7 @@
 #include "macros.hpp"
 #include <cstring>
 #include <ErrorHandler.hpp>
+#include <ServicePool.hpp>
 
 Message::Message(uint8_t serviceType, uint8_t messageType, Message::PacketType packetType, uint16_t applicationId)
     : serviceType(serviceType), messageType(messageType), packetType(packetType), applicationId(applicationId) {}
@@ -36,11 +37,15 @@ void Message::appendBits(uint8_t numBits, uint16_t data) {
 
 void Message::finalize() {
 	// Define the spare field in telemetry and telecommand user data field (7.4.3.2.c and 7.4.4.2.c)
-
 	if (currentBit != 0) {
 		currentBit = 0;
+		data[dataSize] = 0; // Make sure that the last bit is zero
 		dataSize++;
 	}
+
+	if (packetType == PacketType::TM) {
+		messageTypeCounter = Services.getMessageTypeCounter(serviceType, messageType);
+	}
 }
 
 void Message::appendByte(uint8_t value) {
diff --git a/src/ServicePool.cpp b/src/ServicePool.cpp
index f76e2ee77d066b475c0678baec2159ad3dc1a246..7c203e7f2c10473ee1d5d104fdf7202ee18ef738 100644
--- a/src/ServicePool.cpp
+++ b/src/ServicePool.cpp
@@ -12,3 +12,8 @@ void ServicePool::reset() {
 	// statically allocated from before.
 	new (this) ServicePool();
 }
+
+uint16_t ServicePool::getMessageTypeCounter(uint8_t serviceType, uint8_t messageType) {
+	uint16_t key = (serviceType << 8u) | messageType; // Create the key of the map
+	return (messageTypeCounter[key])++; // Fetch and increase the value
+}
diff --git a/test/Message.cpp b/test/Message.cpp
index 25f098322d48d4ec9b80f8fce62937653b22b9ac..8088d9450b8a770effb82d3f1d0a2f9f8add94f0 100644
--- a/test/Message.cpp
+++ b/test/Message.cpp
@@ -253,3 +253,40 @@ TEST_CASE("Spare field", "[message]") {
 
 	CHECK(message9.dataSize == 3);
 }
+
+TEST_CASE("Message type counter", "[message]") {
+	SECTION("Message counting") {
+		Message message1(0, 0, Message::TM, 0);
+		message1.finalize();
+		CHECK(message1.messageTypeCounter == 0);
+
+		Message message2(0, 0, Message::TM, 0);
+		message2.finalize();
+		CHECK(message2.messageTypeCounter == 1);
+	}
+
+	SECTION("Different message types") {
+		Message message1(0, 1, Message::TM, 0);
+		message1.finalize();
+		CHECK(message1.messageTypeCounter == 0);
+
+		Message message2(0, 2, Message::TM, 0);
+		message2.finalize();
+		CHECK(message2.messageTypeCounter == 0);
+	}
+
+	SECTION("Message counter overflow") {
+		for (int i = 0; i <= 65534; i++) {
+			Message message(0, 3, Message::TM, 0);
+			message.finalize();
+		}
+
+		Message message1(0, 3, Message::TM, 0);
+		message1.finalize();
+		CHECK(message1.messageTypeCounter == 65535);
+
+		Message message2(0, 3, Message::TM, 0);
+		message2.finalize();
+		CHECK(message2.messageTypeCounter == 0);
+	}
+}