diff --git a/docs/reference/glib/tmpl/string_utils.sgml b/docs/reference/glib/tmpl/string_utils.sgml
index faaec7d..76cac8a 100644
--- a/docs/reference/glib/tmpl/string_utils.sgml
+++ b/docs/reference/glib/tmpl/string_utils.sgml
@@ -775,6 +775,7 @@ them. Additionally all characters in the range 0x01-0x1F (everything
 below SPACE) and in the range 0x7F-0xFF (all non-ASCII chars) are
 replaced with a '\' followed by their octal representation. Characters
 supplied in @exceptions are not escaped.
+See g_utf8_strescape() for a function that doesn't mangle UTF-8 characters.
 </para>
 
 <para>
diff --git a/glib/glib.symbols b/glib/glib.symbols
index ee9da31..b959049 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -1506,6 +1506,7 @@ g_utf8_offset_to_pointer
 g_utf8_pointer_to_offset
 g_utf8_prev_char
 g_utf8_strchr
+g_utf8_strescape
 g_utf8_strlen
 g_utf8_strncpy
 g_utf8_strrchr
diff --git a/glib/gunicode.h b/glib/gunicode.h
index 78b259e..1e5bb3c 100644
--- a/glib/gunicode.h
+++ b/glib/gunicode.h
@@ -297,6 +297,10 @@ gchar* g_utf8_strncpy (gchar       *dest,
 		       const gchar *src,
 		       gsize        n);
 
+gchar *
+g_utf8_strescape      (const gchar *source,
+                       const gchar *exceptions);
+
 /* Find the UTF-8 character corresponding to ch, in string p. These
    functions are equivalants to strchr and strrchr */
 gchar* g_utf8_strchr  (const gchar *p,
diff --git a/glib/gutf8.c b/glib/gutf8.c
index 27b1e4c..18c80bd 100644
--- a/glib/gutf8.c
+++ b/glib/gutf8.c
@@ -410,6 +410,65 @@ g_utf8_strncpy (gchar       *dest,
   return dest;
 }
 
+/**
+ * g_utf8_strescape:
+ * @source: a string to escape
+ * @exceptions: a string of characters not to escape in source
+ *
+ * Escapes the special characters '\b', '\f', '\n', '\r', '\t', '\' and '"' in
+ * the string source by inserting a '\' before them. Characters supplied in
+ * exceptions are not escaped.
+ * Unlike g_strescape() UTF-8 characters are preseved.
+ *
+ * Return value: a newly-allocated copy of @source with certain characters
+ *   escaped. See above.
+ *
+ * Since: 2.24
+ **/
+gchar *
+g_utf8_strescape (const gchar *source,
+                  const gchar *exceptions)
+{
+  GString *result = g_string_new (NULL);
+
+  while (TRUE)
+    {
+      gchar c = *source++;
+
+      switch (c)
+        {
+        case '\0':
+          goto done;
+        case '\n':
+          g_string_append (result, "\\n");
+          break;
+        case '\"':
+          g_string_append (result, "\\\"");
+          break;
+        case '\\':
+          g_string_append (result, "\\\\");
+          break;
+        case '\b':
+          g_string_append (result, "\\b");
+          break;
+        case '\f':
+          g_string_append (result, "\\f");
+          break;
+        case '\r':
+          g_string_append (result, "\\r");
+          break;
+        case '\t':
+          g_string_append (result, "\\t");
+          break;
+        default:
+          g_string_append_c (result, c);
+        }
+    }
+
+ done:
+  return g_string_free (result, FALSE);
+}
+
 G_LOCK_DEFINE_STATIC (aliases);
 
 static GHashTable *
