diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 6b01ccaceea2f..f530009585ece 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -1664,6 +1664,32 @@ pub trait Iterator {
             .map(|(_, x)| x)
     }
 
+    /// Returns the element that gives the maximum value with respect to the
+    /// specified comparison function.
+    ///
+    /// Returns the rightmost element if the comparison determines two elements
+    /// to be equally maximum.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iter_max_by)]
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
+    /// ```
+    #[inline]
+    #[unstable(feature = "iter_max_by", issue="36105")]
+    fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+    {
+        select_fold1(self,
+                     |_| (),
+                     // switch to y even if it is only equal, to preserve
+                     // stability.
+                     |_, x, _, y| Ordering::Greater != compare(x, y))
+            .map(|(_, x)| x)
+    }
+
     /// Returns the element that gives the minimum value from the
     /// specified function.
     ///
@@ -1688,6 +1714,33 @@ pub trait Iterator {
             .map(|(_, x)| x)
     }
 
+    /// Returns the element that gives the minimum value with respect to the
+    /// specified comparison function.
+    ///
+    /// Returns the latest element if the comparison determines two elements
+    /// to be equally minimum.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iter_min_by)]
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
+    /// ```
+    #[inline]
+    #[unstable(feature = "iter_min_by", issue="36105")]
+    fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+    {
+        select_fold1(self,
+                     |_| (),
+                     // switch to y even if it is strictly smaller, to
+                     // preserve stability.
+                     |_, x, _, y| Ordering::Greater == compare(x, y))
+            .map(|(_, x)| x)
+    }
+
+
     /// Reverses an iterator's direction.
     ///
     /// Usually, iterators iterate from left to right. After using `rev()`,
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index a2848faa105e9..27eb25537f31b 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -664,12 +664,24 @@ fn test_max_by_key() {
     assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10);
 }
 
+#[test]
+fn test_max_by() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().max_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), -10);
+}
+
 #[test]
 fn test_min_by_key() {
     let xs: &[isize] = &[-3, 0, 1, 5, -10];
     assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0);
 }
 
+#[test]
+fn test_min_by() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().min_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), 0);
+}
+
 #[test]
 fn test_by_ref() {
     let mut xs = 0..10;
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 9428b4096bfec..b4c94509477a3 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -33,6 +33,8 @@
 #![feature(try_from)]
 #![feature(unicode)]
 #![feature(unique)]
+#![feature(iter_max_by)]
+#![feature(iter_min_by)]
 
 extern crate core;
 extern crate test;