diff --git a/include/opendht/value.h b/include/opendht/value.h
index 5677d459050c5377ec3a42394f7c1ff5b04a8681..b7452aa19b9b1ad7721e373ee9ad38a38ed41f13 100644
--- a/include/opendht/value.h
+++ b/include/opendht/value.h
@@ -43,6 +43,7 @@
 
 namespace dht {
 
+static const std::string VALUE_KEY_PRIO("p");
 struct Value;
 struct Query;
 
@@ -408,7 +409,9 @@ struct OPENDHT_PUBLIC Value
 
     Value(Value&& o) noexcept
      : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
-     type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq), signature(std::move(o.signature)), cypher(std::move(o.cypher)) {}
+     type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
+     , signature(std::move(o.signature)), cypher(std::move(o.cypher))
+     , priority(o.priority) {}
 
     template <typename Type>
     Value(const Type& vs)
@@ -518,9 +521,12 @@ struct OPENDHT_PUBLIC Value
     template <typename Packer>
     void msgpack_pack(Packer& pk) const
     {
-        pk.pack_map(2);
+        pk.pack_map(2 + (priority?1:0));
         pk.pack(std::string("id"));  pk.pack(id);
         pk.pack(std::string("dat")); msgpack_pack_to_encrypt(pk);
+        if (priority) {
+            pk.pack(VALUE_KEY_PRIO);  pk.pack(priority);
+        }
     }
 
     template <typename Packer>
@@ -602,6 +608,13 @@ struct OPENDHT_PUBLIC Value
      */
     Blob cypher {};
 
+    /**
+     * Priority of this value (used for push notifications)
+     * 0 = high priority
+     * 1 = normal priority
+     */
+    unsigned priority {0};
+
 private:
     friend class SecureDht;
     /* Cache for crypto ops */
diff --git a/src/value.cpp b/src/value.cpp
index ed2a10d1a0f9a28e663b9cb4c38f2e5d6dcd5824..181b17d676d0e7a9224c9b45f8fdb3964b2072aa 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -108,6 +108,10 @@ Value::msgpack_unpack(const msgpack::object& o)
         msgpack_unpack_body(*rdat);
     } else
         throw msgpack::type_error();
+
+    if (auto rprio = findMapValue(o, VALUE_KEY_PRIO)) {
+        priority = rprio->as<unsigned>();
+    }
 }
 
 void
@@ -195,6 +199,9 @@ Value::Value(const Json::Value& json)
     const auto& jutype = json["utype"];
     if (jutype.isString())
         user_type = jutype.asString();
+    const auto& jprio = json["prio"];
+    if (jprio.isIntegral())
+        priority = jprio.asUInt();
 }
 
 Json::Value
@@ -219,6 +226,8 @@ Value::toJson() const
         if (not user_type.empty())
             val["utype"] = user_type;
     }
+    if (priority)
+        val["prio"] = priority;
     return val;
 }