diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
--- a/libcxx/include/__functional_base
+++ b/libcxx/include/__functional_base
@@ -380,12 +380,22 @@
 private:
     type* __f_;
 
+#ifndef _LIBCPP_CXX03_LANG
+    static void __fun(_Tp&) _NOEXCEPT;
+    static void __fun(_Tp&&) = delete;
+#endif
+
 public:
     // construct/copy/destroy
+#ifdef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
         : __f_(_VSTD::addressof(__f)) {}
-#ifndef _LIBCPP_CXX03_LANG
-    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
+#else
+    template <class _Up, class = _EnableIf<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(_VSTD::declval<_Up>())) >>
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(_VSTD::declval<_Up>()))) {
+        type& __f = static_cast<_Up&&>(__u);
+        __f_ = _VSTD::addressof(__f);
+    }
 #endif
 
     // access
@@ -508,6 +518,10 @@
 #endif // _LIBCPP_CXX03_LANG
 };
 
+#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
+template <class _Tp>
+reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
+#endif
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
diff --git a/libcxx/include/functional b/libcxx/include/functional
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -42,8 +42,8 @@
     typedef see below result_type; // Not always defined
 
     // construct/copy/destroy
-    reference_wrapper(T&) noexcept;
-    reference_wrapper(T&&) = delete; // do not bind to temps
+    template<class U>
+      reference_wrapper(U&&);
     reference_wrapper(const reference_wrapper<T>& x) noexcept;
 
     // assignment
@@ -59,6 +59,9 @@
           operator() (ArgTypes&&...) const;
 };
 
+template <class T>
+  reference_wrapper(T&) -> reference_wrapper<T>;
+
 template <class T> reference_wrapper<T> ref(T& t) noexcept;
 template <class T> void ref(const T&& t) = delete;
 template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.assign/copy_assign.pass.cpp
@@ -21,6 +21,12 @@
 {
 };
 
+struct convertible_to_int_ref {
+    int val = 0;
+    operator int&() { return val; }
+    operator int const&() const { return val; }
+};
+
 template <class T>
 void
 test(T& t)
@@ -56,5 +62,19 @@
     const int j = 0;
     test(j);
 
+#if TEST_STD_VER >= 11
+    convertible_to_int_ref convi;
+    test(convi);
+    convertible_to_int_ref const convic;
+    test(convic);
+
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_assignable<Ref&, int&>::value), "");
+    static_assert((!std::is_assignable<Ref&, int>::value), "");
+    static_assert((!std::is_assignable<Ref&, int&&>::value), "");
+    }
+#endif
+
   return 0;
 }
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp
new file mode 100644
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/deduct.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: libcpp-no-deduction-guides
+
+// <functional>
+
+// template <class T>
+//   reference_wrapper(T&) -> reference_wrapper<T>;
+
+#include <functional>
+
+int main()
+{
+    int i = 0;
+    std::reference_wrapper ri(i);
+    static_assert(std::is_same<decltype(ri), std::reference_wrapper<int>>::value, "");
+    const int j = 0;
+    std::reference_wrapper rj(j);
+    static_assert(std::is_same<decltype(rj), std::reference_wrapper<const int>>::value, "");
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
new file mode 100644
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+//   reference_wrapper(U&&) noexcept(see below);
+
+#include <functional>
+#include <cassert>
+
+struct convertible_to_int_ref {
+    int val = 0;
+    operator int&() { return val; }
+    operator int const&() const { return val; }
+};
+
+template <bool IsNothrow>
+struct nothrow_convertible {
+    int val = 0;
+    operator int&() noexcept(IsNothrow) { return val; }
+};
+
+struct convertible_from_int {
+    convertible_from_int(int) {}
+};
+
+void meow(std::reference_wrapper<int>) {}
+void meow(convertible_from_int) {}
+
+int gi;
+std::reference_wrapper<int> purr() { return gi; };
+
+template <class T>
+void
+test(T& t)
+{
+    std::reference_wrapper<T> r(t);
+    assert(&r.get() == &t);
+}
+
+void f() {}
+
+int main()
+{
+    convertible_to_int_ref convi;
+    test(convi);
+    convertible_to_int_ref const convic;
+    test(convic);
+
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_nothrow_constructible<Ref, nothrow_convertible<true>>::value), "");
+    static_assert((!std::is_nothrow_constructible<Ref, nothrow_convertible<false>>::value), "");
+    }
+
+    {
+    meow(0);
+    (true) ? purr() : 0;
+    }
+
+#ifdef __cpp_deduction_guides
+    {
+    int i = 0;
+    std::reference_wrapper ri(i);
+    static_assert((std::is_same<decltype(ri), std::reference_wrapper<int>>::value), "" );
+    const int j = 0;
+    std::reference_wrapper rj(j);
+    static_assert((std::is_same<decltype(rj), std::reference_wrapper<const int>>::value), "" );
+    }
+#endif
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
new file mode 100644
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor2.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <functional>
+//
+// reference_wrapper
+//
+// template <class U>
+//   reference_wrapper(U&&);
+
+#include <functional>
+#include <cassert>
+
+struct B {} b;
+
+struct A1 {
+    operator B& () const { return b; }
+};
+struct A2 {
+    operator B& () const noexcept { return b; }
+};
+
+int main()
+{
+    {
+    std::reference_wrapper<B> b1 = A1();
+    assert(&b1.get() == &b);
+    b1 = A1();
+    assert(&b1.get() == &b);
+
+    static_assert(std::is_convertible<A1, std::reference_wrapper<B>>::value, "");
+    static_assert(!std::is_nothrow_constructible<std::reference_wrapper<B>, A1>::value, "");
+#if TEST_STD_VER >= 20
+    static_assert(!std::is_nothrow_convertible_v<A1, std::reference_wrapper<B>>);
+#endif
+    static_assert(std::is_assignable<std::reference_wrapper<B>, A1>::value, "");
+    static_assert(!std::is_nothrow_assignable<std::reference_wrapper<B>, A1>::value, "");
+    }
+
+    {
+    std::reference_wrapper<B> b2 = A2();
+    assert(&b2.get() == &b);
+    b2 = A2();
+    assert(&b2.get() == &b);
+
+    static_assert(std::is_convertible<A2, std::reference_wrapper<B>>::value, "");
+    static_assert(std::is_nothrow_constructible<std::reference_wrapper<B>, A2>::value, "");
+#if TEST_STD_VER >= 20
+    static_assert(std::is_nothrow_convertible_v<A2, std::reference_wrapper<B>>);
+#endif
+    static_assert(std::is_assignable<std::reference_wrapper<B>, A2>::value, "");
+    static_assert(std::is_nothrow_assignable<std::reference_wrapper<B>, A2>::value, "");
+    }
+}
diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_ctor.pass.cpp
@@ -14,6 +14,7 @@
 
 #include <functional>
 #include <cassert>
+#include <type_traits>
 
 #include "test_macros.h"
 
@@ -43,5 +44,21 @@
     const int j = 0;
     test(j);
 
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_constructible<Ref, int&>::value), "");
+    static_assert((!std::is_constructible<Ref, int>::value), "");
+    static_assert((!std::is_constructible<Ref, int&&>::value), "");
+    }
+
+#if TEST_STD_VER >= 11
+    {
+    using Ref = std::reference_wrapper<int>;
+    static_assert((std::is_nothrow_constructible<Ref, int&>::value), "");
+    static_assert((!std::is_nothrow_constructible<Ref, int>::value), "");
+    static_assert((!std::is_nothrow_constructible<Ref, int&&>::value), "");
+    }
+#endif
+
   return 0;
 }