diff --git a/include/string.h b/include/string.h
index f0dc21814897..1b6e1849de43 100644
--- a/include/string.h
+++ b/include/string.h
@@ -59,6 +59,7 @@ __BEGIN_DECLS
 void	*memccpy(void * __restrict, const void * __restrict, int, size_t);
 #endif
 void	*memchr(const void *, int, size_t) __pure;
+void	*memrchr(const void *, int, size_t) __pure;
 int	 memcmp(const void *, const void *, size_t) __pure;
 void	*memcpy(void * __restrict, const void * __restrict, size_t);
 #if __BSD_VISIBLE
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index 6d64ea5a08c9..9e5f0dab9b3b 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -7,7 +7,7 @@ CFLAGS+= -I${.CURDIR}/locale
 
 # machine-independent string sources
 MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c fls.c flsl.c index.c memccpy.c \
-	memchr.c memcmp.c \
+	memchr.c memrchr.c memcmp.c \
 	memcpy.c memmem.c memmove.c memset.c rindex.c stpcpy.c strcasecmp.c \
 	strcat.c strchr.c strcmp.c strcoll.c strcpy.c strcspn.c strdup.c \
 	strerror.c strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c \
@@ -39,6 +39,7 @@ MLINKS+=ffs.3 ffsl.3
 MLINKS+=ffs.3 fls.3
 MLINKS+=ffs.3 flsl.3
 MLINKS+=index.3 rindex.3
+MLINKS+=memchr.3 memrchr.3
 MLINKS+=strcasecmp.3 strncasecmp.3
 MLINKS+=strcat.3 strncat.3
 MLINKS+=strchr.3 strrchr.3
diff --git a/lib/libc/string/Symbol.map b/lib/libc/string/Symbol.map
index ad9f74327f13..d034ecce718b 100644
--- a/lib/libc/string/Symbol.map
+++ b/lib/libc/string/Symbol.map
@@ -77,6 +77,10 @@ FBSD_1.0 {
 	wmemset;
 };
 
+FBSD_1.1 {
+	memrchr;
+};
+
 FBSDprivate_1.0 {
 	__strtok_r;
 };
diff --git a/lib/libc/string/memchr.3 b/lib/libc/string/memchr.3
index d82d859dd0f1..5cbaf6cc1779 100644
--- a/lib/libc/string/memchr.3
+++ b/lib/libc/string/memchr.3
@@ -32,7 +32,7 @@
 .\"     @(#)memchr.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd June 4, 1993
+.Dd April 9, 2008
 .Dt MEMCHR 3
 .Os
 .Sh NAME
@@ -44,6 +44,8 @@
 .In string.h
 .Ft void *
 .Fn memchr "const void *b" "int c" "size_t len"
+.Ft void *
+.Fn memrchr "const void *b" "int c" "size_t len"
 .Sh DESCRIPTION
 The
 .Fn memchr
@@ -53,11 +55,22 @@ locates the first occurrence of
 (converted to an unsigned char)
 in string
 .Fa b .
+.Pp
+The
+.Fn memrchr
+function behaves like
+.Fn memchr ,
+except that it locates the last occurrence of
+.Fa c
+in string
+.Fa b .
 .Sh RETURN VALUES
 The
 .Fn memchr
-function
-returns a pointer to the byte located,
+and
+.Fn memrchr
+functions
+return a pointer to the byte located,
 or NULL if no such byte exists within
 .Fa len
 bytes.
@@ -77,3 +90,15 @@ The
 function
 conforms to
 .St -isoC .
+.Pp
+The
+.Fn memrchr       
+function is a GNU extension and conforms to no standard.
+.Sh HISTORY
+The
+.Fn memrchr
+function first appeared in GNU libc 2.1.91, this implementation
+first appeared in
+.Fx 8.0 ,
+coming from
+.Ox 4.3 .
diff --git a/lib/libc/string/memrchr.c b/lib/libc/string/memrchr.c
new file mode 100644
index 000000000000..f477bc356491
--- /dev/null
+++ b/lib/libc/string/memrchr.c
@@ -0,0 +1,40 @@
+/*	$OpenBSD: memrchr.c,v 1.2 2007/11/27 16:22:12 martynas Exp $	*/
+
+/*
+ * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#include <string.h>
+
+/*
+ * Reverse memchr()
+ * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
+ */
+void *
+memrchr(const void *s, int c, size_t n)
+{
+	const unsigned char *cp;
+
+	if (n != 0) {
+		cp = (unsigned char *)s + n;
+		do {
+			if (*(--cp) == (unsigned char)c)
+				return((void *)cp);
+		} while (--n != 0);
+	}
+	return(NULL);
+}
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 6a82581ab250..d9d51255cf66 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 800033	/* Master, propagated to newvers */
+#define __FreeBSD_version 800034	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>