diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index d69f50a9a2f4938e26cc3c0f1b80948b45609238..e2baf38e0beb05d68eef54b5ccf26faa80ec3f84 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -885,6 +885,8 @@ public:
 
   virtual RuntimeDefinition getRuntimeDefinition() const;
 
+  virtual bool argumentsMayEscape() const;
+
   virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
                                             BindingsTy &Bindings) const;
 
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 82a1aa22579c1fea27b8be3b103c0d65d2dd648a..87d7e89e52ebe0b70af08815faaaf269aaf3dbc4 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1907,7 +1907,8 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
     // that the pointers get freed by following the container itself.
     if (FirstSlot.startswith("addPointer") ||
         FirstSlot.startswith("insertPointer") ||
-        FirstSlot.startswith("replacePointer")) {
+        FirstSlot.startswith("replacePointer") ||
+        FirstSlot.equals("valueWithPointer")) {
       return true;
     }
 
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index e0392bd147301a6466930789298693eecc010a41..838d273cc0af188785ed53cc87c601e2aecde985 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -886,6 +886,17 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
   return RuntimeDefinition();
 }
 
+bool ObjCMethodCall::argumentsMayEscape() const {
+  if (isInSystemHeader() && !isInstanceMessage()) {
+    Selector Sel = getSelector();
+    if (Sel.getNumArgs() == 1 &&
+        Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
+      return true;
+  }
+
+  return CallEvent::argumentsMayEscape();
+}
+
 void ObjCMethodCall::getInitialStackFrameContents(
                                              const StackFrameContext *CalleeCtx,
                                              BindingsTy &Bindings) const {
diff --git a/test/Analysis/Inputs/system-header-simulator-objc.h b/test/Analysis/Inputs/system-header-simulator-objc.h
index 3e1d9555bbde154d8b475c787a07b27d14ee27ea..8a5d3b6403c8913a23c7f1fac78f2aec1dd9a0d5 100644
--- a/test/Analysis/Inputs/system-header-simulator-objc.h
+++ b/test/Analysis/Inputs/system-header-simulator-objc.h
@@ -66,8 +66,11 @@ typedef struct {
 NSFastEnumerationState;
 @protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
 @end           @class NSString, NSDictionary;
-@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
-@end  @interface NSNumber : NSValue  - (char)charValue;
+@interface NSValue : NSObject <NSCopying, NSCoding>
++ (NSValue *)valueWithPointer:(const void *)p;
+- (void)getValue:(void *)value;
+@end
+@interface NSNumber : NSValue  - (char)charValue;
 - (id)initWithInt:(int)value;
 @end   @class NSString;
 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m
index ad16db52dff966f08cfdafc0e1de58d4cd1ce2c9..9201c2b75fe6a94023f3246a4c907e972f104b87 100644
--- a/test/Analysis/malloc.m
+++ b/test/Analysis/malloc.m
@@ -49,4 +49,9 @@ void _ArrayCreate() {
 void testNSDataTruePositiveLeak() {
   char *b = (char *)malloc(12);
   NSData *d = [[NSData alloc] initWithBytes: b length: 12]; // expected-warning {{Potential leak of memory pointed to by 'b'}}
+}
+
+id wrapInNSValue() {
+  void *buffer = malloc(4);
+  return [NSValue valueWithPointer:buffer]; // no-warning
 }
\ No newline at end of file