diff --git a/doc/examples/json_pointer__back.cpp b/doc/examples/json_pointer__back.cpp
new file mode 100644
index 00000000..3d57c589
--- /dev/null
+++ b/doc/examples/json_pointer__back.cpp
@@ -0,0 +1,15 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // different JSON Pointers
+    json::json_pointer ptr1("/foo");
+    json::json_pointer ptr2("/foo/0");
+
+    // call empty()
+    std::cout << "last reference token of " << ptr1 << " is " << ptr1.back() << '\n'
+              << "last reference token of " << ptr2 << " is " << ptr2.back() << std::endl;
+}
diff --git a/doc/examples/json_pointer__back.link b/doc/examples/json_pointer__back.link
new file mode 100644
index 00000000..adca23d7
--- /dev/null
+++ b/doc/examples/json_pointer__back.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/2q7gu0ZAQoMeOaAc"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/json_pointer__back.output b/doc/examples/json_pointer__back.output
new file mode 100644
index 00000000..da4d0279
--- /dev/null
+++ b/doc/examples/json_pointer__back.output
@@ -0,0 +1,2 @@
+last reference token of "/foo" is foo
+last reference token of "/foo/0" is 0
diff --git a/doc/examples/json_pointer__pop_back.cpp b/doc/examples/json_pointer__pop_back.cpp
new file mode 100644
index 00000000..ed3417ec
--- /dev/null
+++ b/doc/examples/json_pointer__pop_back.cpp
@@ -0,0 +1,21 @@
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create empty JSON Pointer
+    json::json_pointer ptr("/foo/bar/baz");
+    std::cout << ptr << '\n';
+
+    // call pop_back()
+    ptr.pop_back();
+    std::cout << ptr << '\n';
+
+    ptr.pop_back();
+    std::cout << ptr << '\n';
+
+    ptr.pop_back();
+    std::cout << ptr << '\n';
+}
diff --git a/doc/examples/json_pointer__pop_back.link b/doc/examples/json_pointer__pop_back.link
new file mode 100644
index 00000000..a9f9c88b
--- /dev/null
+++ b/doc/examples/json_pointer__pop_back.link
@@ -0,0 +1 @@
+<a target="_blank" href="https://wandbox.org/permlink/aFuDbxgbraVszcBX"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/json_pointer__pop_back.output b/doc/examples/json_pointer__pop_back.output
new file mode 100644
index 00000000..b0468dc5
--- /dev/null
+++ b/doc/examples/json_pointer__pop_back.output
@@ -0,0 +1,4 @@
+"/foo/bar/baz"
+"/foo/bar"
+"/foo"
+""
diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp
index d4d6000a..465e5165 100644
--- a/include/nlohmann/detail/json_pointer.hpp
+++ b/include/nlohmann/detail/json_pointer.hpp
@@ -210,7 +210,7 @@ class json_pointer
     @return parent of this JSON pointer; in case this JSON pointer is the root,
             the root itself is returned
 
-    @complexity Constant.
+    @complexity Linear in the length of the JSON pointer.
 
     @liveexample{The example shows the result of `parent_pointer` for different
     JSON Pointers.,json_pointer__parent_pointer}
@@ -230,19 +230,50 @@ class json_pointer
     }
 
     /*!
-    @brief remove and return last reference token
+    @brief remove last reference token
+
+    @pre not `empty()`
+
+    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
+
+    @complexity Constant.
+
     @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
     */
-    std::string pop_back()
+    void pop_back()
     {
         if (JSON_UNLIKELY(empty()))
         {
             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
         }
 
-        auto last = reference_tokens.back();
         reference_tokens.pop_back();
-        return last;
+    }
+
+    /*!
+    @brief return last reference token
+
+    @pre not `empty()`
+    @return last reference token
+
+    @liveexample{The example shows the usage of `back`.,json_pointer__back}
+
+    @complexity Constant.
+
+    @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
+    */
+    const std::string& back()
+    {
+        if (JSON_UNLIKELY(empty()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        return reference_tokens.back();
     }
 
     /*!
@@ -255,7 +286,7 @@ class json_pointer
     @liveexample{The example shows the result of `push_back` for different
     JSON Pointers.,json_pointer__push_back}
 
-    @since version 0.6.0
+    @since version 3.6.0
     */
     void push_back(const std::string& token)
     {
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 6a5c1075..fd4b09e7 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -7507,7 +7507,8 @@ class basic_json
             }
 
             // get reference to parent of JSON pointer ptr
-            const auto last_path = ptr.pop_back();
+            const auto last_path = ptr.back();
+            ptr.pop_back();
             basic_json& parent = result[ptr];
 
             switch (parent.m_type)
@@ -7552,7 +7553,8 @@ class basic_json
         const auto operation_remove = [&result](json_pointer & ptr)
         {
             // get reference to parent of JSON pointer ptr
-            const auto last_path = ptr.pop_back();
+            const auto last_path = ptr.back();
+            ptr.pop_back();
             basic_json& parent = result.at(ptr);
 
             // remove child
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index c96ddc4d..0f18cfb0 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -8620,7 +8620,7 @@ class json_pointer
     @return parent of this JSON pointer; in case this JSON pointer is the root,
             the root itself is returned
 
-    @complexity Constant.
+    @complexity Linear in the length of the JSON pointer.
 
     @liveexample{The example shows the result of `parent_pointer` for different
     JSON Pointers.,json_pointer__parent_pointer}
@@ -8640,19 +8640,50 @@ class json_pointer
     }
 
     /*!
-    @brief remove and return last reference token
+    @brief remove last reference token
+
+    @pre not `empty()`
+
+    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
+
+    @complexity Constant.
+
     @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
     */
-    std::string pop_back()
+    void pop_back()
     {
         if (JSON_UNLIKELY(empty()))
         {
             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
         }
 
-        auto last = reference_tokens.back();
         reference_tokens.pop_back();
-        return last;
+    }
+
+    /*!
+    @brief return last reference token
+
+    @pre not `empty()`
+    @return last reference token
+
+    @liveexample{The example shows the usage of `back`.,json_pointer__back}
+
+    @complexity Constant.
+
+    @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
+    */
+    const std::string& back()
+    {
+        if (JSON_UNLIKELY(empty()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        return reference_tokens.back();
     }
 
     /*!
@@ -8665,7 +8696,7 @@ class json_pointer
     @liveexample{The example shows the result of `push_back` for different
     JSON Pointers.,json_pointer__push_back}
 
-    @since version 0.6.0
+    @since version 3.6.0
     */
     void push_back(const std::string& token)
     {
@@ -20241,7 +20272,8 @@ class basic_json
             }
 
             // get reference to parent of JSON pointer ptr
-            const auto last_path = ptr.pop_back();
+            const auto last_path = ptr.back();
+            ptr.pop_back();
             basic_json& parent = result[ptr];
 
             switch (parent.m_type)
@@ -20286,7 +20318,8 @@ class basic_json
         const auto operation_remove = [&result](json_pointer & ptr)
         {
             // get reference to parent of JSON pointer ptr
-            const auto last_path = ptr.pop_back();
+            const auto last_path = ptr.back();
+            ptr.pop_back();
             basic_json& parent = result.at(ptr);
 
             // remove child