diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index 2fe9218df54d72b0c965e75983ec99bb312d0f7d..99a86024a235d92ab2860221a52685ffd21c0b8f 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -7,6 +7,11 @@
 
 #define ECSS_MAX_FIXED_OCTET_STRING_SIZE 256u // For the ST13 large packet transfer service
 
+/**
+ * The total number of different message types that can be handled by this project
+ */
+#define ECSS_TOTAL_MESSAGE_TYPES (10 * 20)
+
 // 7.4.1
 #define CCSDS_PACKET_VERSION 0
 
diff --git a/inc/Message.hpp b/inc/Message.hpp
index 6cd0ef1d73f06c6a2dda9fad42d17c8f4c86f3e4..55a5f05b394d7362154f27f2de313cd154c2523b 100644
--- a/inc/Message.hpp
+++ b/inc/Message.hpp
@@ -108,7 +108,7 @@ public:
 	 * multiple of the padding word size declared for the application process
 	 * @todo Confirm that the overall packet size is an integer multiple of the padding word size
 	 * declared for every application process
-	 * @todo check if wee need to define the spare field for the telemetry and telecommand
+	 * @todo check if we need to define the spare field for the telemetry and telecommand
 	 * secondary headers
 	 */
 	void finalize();
diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index 707ae91f1300ba2db2651d7f3297aa9577cf78bc..f6a7ea23ecc2e1d865c9ff3f454249e0b0520f94 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -23,12 +23,16 @@ 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
+	 * Each key-value pair corresponds to one MessageType within a Service. For the key, the most significant 8 bits are
+     * the number of the service, while the least significant 8 bits are the number of the Message. The value is the
+     * counter of each MessageType.
 	 */
-	etl::map<uint16_t, uint16_t, 10*20> messageTypeCounter;
+	etl::map<uint16_t, uint16_t, ECSS_TOTAL_MESSAGE_TYPES> messageTypeCounter;
+
+	/**
+	 * A counter for messages that corresponds to the total number of TM packets sent from an APID
+	 */
+	uint16_t packetSequenceCounter = 0;
 public:
 	RequestVerificationService requestVerification;
 	EventReportService eventReport;
@@ -64,7 +68,16 @@ public:
 	 * @param messageType The message type ID
 	 * @return The message type count
 	 */
-	uint16_t getMessageTypeCounter(uint8_t serviceType, uint8_t messageType);
+	uint16_t getAndUpdateMessageTypeCounter(uint8_t serviceType, uint8_t messageType);
+
+	/**
+	 * Get and increase the "packet sequence count" for the next message
+	 *
+	 * The packet sequence count is incremented each time a packet is released, with a maximum value of 2^14 - 1
+	 *
+	 * @return The packet sequence count
+	 */
+	uint16_t getAndUpdatePacketSequenceCounter();
 };
 
 /**
diff --git a/src/Message.cpp b/src/Message.cpp
index 7fb5974e00e6f59d8574a72c1aad1126be7cdfc0..a5fea247e6a4fa91c2757eeaf90ef8b7bfaf7091 100644
--- a/src/Message.cpp
+++ b/src/Message.cpp
@@ -39,12 +39,13 @@ 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
+		data[dataSize] = 0; // Make sure that the last byte is zero
 		dataSize++;
 	}
 
 	if (packetType == PacketType::TM) {
-		messageTypeCounter = Services.getMessageTypeCounter(serviceType, messageType);
+		messageTypeCounter = Services.getAndUpdateMessageTypeCounter(serviceType, messageType);
+		packetSequenceCount = Services.getAndUpdatePacketSequenceCounter();
 	}
 }
 
diff --git a/src/ServicePool.cpp b/src/ServicePool.cpp
index 7c203e7f2c10473ee1d5d104fdf7202ee18ef738..f3a529fd0cc2a8b0dada8cd2493807a9f2fdc9af 100644
--- a/src/ServicePool.cpp
+++ b/src/ServicePool.cpp
@@ -13,7 +13,18 @@ void ServicePool::reset() {
 	new (this) ServicePool();
 }
 
-uint16_t ServicePool::getMessageTypeCounter(uint8_t serviceType, uint8_t messageType) {
+uint16_t ServicePool::getAndUpdateMessageTypeCounter(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
 }
+
+uint16_t ServicePool::getAndUpdatePacketSequenceCounter() {
+	uint16_t value = packetSequenceCounter;
+
+	// Increase the value
+	if ((++packetSequenceCounter) >= (1u << 14u)) { // The value of the packet sequence counter is <= (2^14 - 1)
+		packetSequenceCounter = 0;
+	}
+
+	return value;
+}
diff --git a/test/Message.cpp b/test/Message.cpp
index 8088d9450b8a770effb82d3f1d0a2f9f8add94f0..f6eba2461bc679f411b37e88eb4f18ce2a33bb97 100644
--- a/test/Message.cpp
+++ b/test/Message.cpp
@@ -1,5 +1,6 @@
 #include <catch2/catch.hpp>
 #include <Message.hpp>
+#include <ServicePool.hpp>
 
 TEST_CASE("Message is usable", "[message]") {
 	Message message(5, 17, Message::TC, 3);
@@ -290,3 +291,37 @@ TEST_CASE("Message type counter", "[message]") {
 		CHECK(message2.messageTypeCounter == 0);
 	}
 }
+
+TEST_CASE("Packet sequence counter", "[message]") {
+	SECTION("Packet counting") {
+		Message message1(0, 0, Message::TM, 0);
+		message1.finalize();
+		CHECK(message1.packetSequenceCount == 0);
+
+		Message message2(0, 0, Message::TM, 0);
+		message2.finalize();
+		CHECK(message2.packetSequenceCount == 1);
+
+		// Different message type check
+		Message message3(1, 2, Message::TM, 0);
+		message3.finalize();
+		CHECK(message3.packetSequenceCount == 2);
+	}
+
+	SECTION("Packet counter overflow") {
+		Services.reset();
+
+		for (int i = 0; i <= 16382; i++) {
+			Message message(0, 3, Message::TM, 0);
+			message.finalize();
+		}
+
+		Message message1(0, 3, Message::TM, 0);
+		message1.finalize();
+		CHECK(message1.packetSequenceCount == 16383);
+
+		Message message2(0, 3, Message::TM, 0);
+		message2.finalize();
+		CHECK(message2.packetSequenceCount == 0);
+	}
+}