diff --git include/clang/AST/NSAPI.h include/clang/AST/NSAPI.h
index 583f9d9..1c82d78 100644
--- include/clang/AST/NSAPI.h
+++ include/clang/AST/NSAPI.h
@@ -207,6 +207,35 @@ public:
   Optional<NSNumberLiteralMethodKind>
       getNSNumberFactoryMethodKind(QualType T) const;
 
+  /// \brief Enumerates the NSValue methods used to generate literals
+  /// and to apply automatic migration
+  enum NSValueMethodKind {
+    NSValueWithBytesObjCType,
+
+    NSValueWithCGPoint,
+    NSValueWithCGVector,
+    NSValueWithCGSize,
+    NSValueWithCGRect,
+    NSValueWithCGAffineTransform,
+
+    NSValueWithUIEdgeInsets,
+    NSValueWithUIOffset,
+
+    NSValueWithCATransform3D,
+
+    NSValueWithRange,
+    NSValueWithPoint,
+    NSValueWithSize,
+    NSValueWithRect,
+    NSValueWithEdgeInsets
+  };
+
+  static const unsigned NumNSValueMethods = 14;
+
+  /// \brief The Objective-C NSValue selectors used to create NSValue literals
+  /// and to apply automatic migration
+  Selector getNSValueSelector(NSValueMethodKind MK) const;
+
   /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
   bool isObjCBOOLType(QualType T) const;
   /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
@@ -249,6 +278,10 @@ private:
   mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
   mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
 
+  /// \brief The Objective-C NSValue selectors used to create NSValue literals
+  /// and to apply automatic migration
+  mutable Selector NSValueSelectors[NumNSValueMethods];
+
   mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
                    setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
                    isEqualSel;
diff --git lib/AST/NSAPI.cpp lib/AST/NSAPI.cpp
index c562dae..e7d3440 100644
--- lib/AST/NSAPI.cpp
+++ lib/AST/NSAPI.cpp
@@ -478,6 +478,72 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
   return None;
 }
 
+Selector NSAPI::getNSValueSelector(NSValueMethodKind MK) const {
+  if (NSValueSelectors[MK].isNull()) {
+    Selector Sel;
+    switch (MK) {
+      case NSValueWithBytesObjCType: {
+        IdentifierInfo *KeyIdents[] = {
+          &Ctx.Idents.get("valueWithBytes"),
+          &Ctx.Idents.get("objCType")
+        };
+        Sel = Ctx.Selectors.getSelector(2, KeyIdents);
+      } break;
+      case NSValueWithCGPoint:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                          &Ctx.Idents.get("valueWithCGPoint"));
+        break;
+      case NSValueWithCGVector:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                          &Ctx.Idents.get("valueWithCGVector"));
+        break;
+      case NSValueWithCGSize:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                            &Ctx.Idents.get("valueWithCGSize"));
+        break;
+      case NSValueWithCGRect:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                            &Ctx.Idents.get("valueWithCGRect"));
+        break;
+      case NSValueWithCGAffineTransform:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                &Ctx.Idents.get("valueWithCGAffineTransform"));
+        break;
+      case NSValueWithUIEdgeInsets:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                      &Ctx.Idents.get("valueWithUIEdgeInsets"));
+        break;
+      case NSValueWithUIOffset:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                         &Ctx.Idents.get("valueWithUIOffset"));
+        break;
+      case NSValueWithCATransform3D:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                     &Ctx.Idents.get("valueWithCATransform3D"));
+        break;
+      case NSValueWithRange:
+        Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("valueWithRange"));
+        break;
+      case NSValueWithPoint:
+        Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("valueWithPoint"));
+        break;
+      case NSValueWithSize:
+        Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("valueWithSize"));
+        break;
+      case NSValueWithRect:
+        Sel = Ctx.Selectors.getUnarySelector(&Ctx.Idents.get("valueWithRect"));
+        break;
+      case NSValueWithEdgeInsets:
+        Sel = Ctx.Selectors.getUnarySelector(
+                                       &Ctx.Idents.get("valueWithEdgeInsets"));
+        break;
+    }
+    NSValueSelectors[MK] = Sel;
+  }
+
+  return NSValueSelectors[MK];
+}
+
 /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
 bool NSAPI::isObjCBOOLType(QualType T) const {
   return isObjCTypedef(T, "BOOL", BOOLId);
diff --git lib/Edit/RewriteObjCFoundationAPI.cpp lib/Edit/RewriteObjCFoundationAPI.cpp
index 482c0f6..a858d31 100644
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -335,6 +335,8 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
                                             const NSAPI &NS, Commit &commit);
 static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg,
                                            const NSAPI &NS, Commit &commit);
+static bool rewriteToObjCBoxableExpression(const ObjCMessageExpr *Msg,
+                                           const NSAPI &NS, Commit &commit);
 
 bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
                                       const NSAPI &NS, Commit &commit,
@@ -351,6 +353,8 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
     return rewriteToNumberLiteral(Msg, NS, commit);
   if (II == NS.getNSClassId(NSAPI::ClassId_NSString))
     return rewriteToStringBoxedExpression(Msg, NS, commit);
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSValue))
+    return rewriteToObjCBoxableExpression(Msg, NS, commit);
 
   return false;
 }
@@ -1171,3 +1175,60 @@ static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg,
 
   return false;
 }
+
+static bool rewriteToObjCBoxableExpression(const ObjCMessageExpr *Msg,
+                                           const NSAPI &NS, Commit &commit) {
+  int NumArgs = Msg->getNumArgs();
+  if (NumArgs != 2 && NumArgs != 1) {
+    return false;
+  }
+
+  Selector Sel = Msg->getSelector();
+
+  if (Sel == NS.getNSValueSelector(NSAPI::NSValueWithBytesObjCType) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCATransform3D) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCGAffineTransform) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCGPoint) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCGRect) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCGSize) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithCGVector) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithEdgeInsets) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithPoint) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithRange) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithRect) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithSize) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithUIEdgeInsets) ||
+      Sel == NS.getNSValueSelector(NSAPI::NSValueWithUIOffset)) {
+
+    const Expr *Arg = Msg->getArg(0)->IgnoreCasts();
+
+    // handles 'valueWithBytes' specific case
+    // [NSValue valueWithBytes:&unaryOperation objCType:@encode(SomeType)]
+    //                         ^
+    if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Arg)) {
+      Arg = UO->getSubExpr();
+    }
+
+    QualType ArgType = Arg->getType();
+
+    // handles 'valueWithBytes' specific case
+    // [NSValue valueWithBytes:&unaryOperation objCType:@encode(SomeType)]
+    //                         ^-------------^
+    if (ArgType->isPointerType()) {
+      ArgType = ArgType->getPointeeType();
+    }
+
+    if (!ArgType->isObjCBoxableRecordType()) {
+      return false;
+    }
+
+    SourceRange MsgRange(Msg->getLocStart(), Msg->getLocEnd());
+    SourceRange ArgRange(Arg->getLocStart(), Arg->getLocEnd());
+    commit.replaceWithInner(MsgRange, ArgRange);
+    commit.insertWrap("@(", ArgRange, ")");
+
+    return true;
+  }
+
+  return false;
+}
diff --git test/ARCMT/objcmt-objc-boxable.m test/ARCMT/objcmt-objc-boxable.m
new file mode 100644
index 0000000..db5459b
--- /dev/null
+++ test/ARCMT/objcmt-objc-boxable.m
@@ -0,0 +1,176 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -mt-migrate-directory %t %s -x objective-c
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
+
+typedef unsigned long NSUInteger;
+typedef double CGFloat;
+
+typedef struct _NSRange {
+    NSUInteger location;
+    NSUInteger length;
+} NSRange;
+
+typedef struct CATransform3D
+{
+  CGFloat m11, m12, m13, m14;
+  CGFloat m21, m22, m23, m24;
+  CGFloat m31, m32, m33, m34;
+  CGFloat m41, m42, m43, m44;
+} CATransform3D;
+
+typedef struct CGPoint {
+    CGFloat x;
+    CGFloat y;
+} CGPoint;
+
+typedef struct CGSize {
+    CGFloat width;
+    CGFloat height;
+} CGSize;
+
+typedef struct CGVector {
+    CGFloat dx;
+    CGFloat dy;
+} CGVector;
+
+typedef struct CGRect {
+    CGPoint origin;
+    CGSize size;
+} CGRect;
+
+typedef struct UIEdgeInsets {
+    CGFloat top, left, bottom, right;
+} UIEdgeInsets;
+
+typedef struct UIOffset {
+    CGFloat horizontal, vertical;
+} UIOffset;
+
+typedef struct CGAffineTransform {
+  CGFloat a, b, c, d;
+  CGFloat tx, ty;
+} CGAffineTransform;
+
+typedef CGPoint NSPoint;
+typedef CGSize NSSize;
+typedef CGRect NSRect;
+
+typedef struct NSEdgeInsets {
+    CGFloat top;
+    CGFloat left;
+    CGFloat bottom;
+    CGFloat right;
+} NSEdgeInsets;
+
+typedef struct CustomStruct {
+    int dummy;
+} CustomStruct;
+
+typedef struct AnotherCustomStruct {
+    int dummy;
+} AnotherCustomStruct;
+
+extern CGRect returnRect();
+
+@interface NSObject @end
+
+@interface NSValue : NSObject
+
++ (NSValue *)valueWithCGPoint:(CGPoint)point;
++ (NSValue *)valueWithCGVector:(CGVector)vector;
++ (NSValue *)valueWithCGSize:(CGSize)size;
++ (NSValue *)valueWithCGRect:(CGRect)rect;
++ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
++ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
++ (NSValue *)valueWithUIOffset:(UIOffset)insets;
+
++ (NSValue *)valueWithRange:(NSRange)range;
++ (NSValue *)valueWithCATransform3D:(CATransform3D)t;
+
++ (NSValue *)valueWithPoint:(NSPoint)point;
++ (NSValue *)valueWithSize:(NSSize)size;
++ (NSValue *)valueWithRect:(NSRect)rect;
++ (NSValue *)valueWithEdgeInsets:(NSEdgeInsets)insets;
+
++ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;
+
+@end
+
+static CGPoint cg_point;
+static CGVector cg_vector;
+static CGSize cg_size;
+static CGRect cg_rect;
+static CGAffineTransform ca_affineTransform;
+static UIEdgeInsets ui_edgeInsets;
+static UIOffset ui_offset;
+static NSRange ns_range;
+static CATransform3D ca_transform3D;
+static NSPoint ns_point;
+static NSSize ns_size;
+static NSRect ns_rect;
+static NSEdgeInsets ns_edgeInsets;
+static CustomStruct customStruct;
+static AnotherCustomStruct anotherCustomStruct;
+
+void noBoxableStructsAvailableYet() {
+  [NSValue valueWithCGPoint:cg_point];
+  [NSValue valueWithCGVector:cg_vector];
+  [NSValue valueWithCGSize:cg_size];
+  [NSValue valueWithCGRect:cg_rect];
+  [NSValue valueWithCGAffineTransform:ca_affineTransform];
+  [NSValue valueWithUIEdgeInsets:ui_edgeInsets];
+  [NSValue valueWithUIOffset:ui_offset];
+
+  [NSValue valueWithRange:ns_range];
+  [NSValue valueWithCATransform3D:ca_transform3D];
+
+  [NSValue valueWithPoint:ns_point];
+  [NSValue valueWithSize:ns_size];
+  [NSValue valueWithRect:ns_rect];
+  [NSValue valueWithEdgeInsets:ns_edgeInsets];
+
+  [NSValue valueWithBytes:&customStruct objCType:@encode(CustomStruct)];
+  [NSValue valueWithBytes:&anotherCustomStruct objCType:@encode(AnotherCustomStruct)];
+  [NSValue valueWithRect:returnRect()];
+}
+
+#define BOXABLE __attribute__((objc_boxable))
+
+typedef struct BOXABLE _NSRange NSRange;
+typedef struct BOXABLE CATransform3D CATransform3D;
+typedef struct BOXABLE CGPoint CGPoint;
+typedef struct BOXABLE CGSize CGSize;
+typedef struct BOXABLE CGVector CGVector;
+typedef struct BOXABLE CGRect CGRect;
+typedef struct BOXABLE UIEdgeInsets UIEdgeInsets;
+typedef struct BOXABLE UIOffset UIOffset;
+typedef struct BOXABLE CGAffineTransform CGAffineTransform;
+typedef struct BOXABLE CGPoint NSPoint;
+typedef struct BOXABLE CGSize NSSize;
+typedef struct BOXABLE CGRect NSRect;
+typedef struct BOXABLE NSEdgeInsets NSEdgeInsets;
+typedef struct BOXABLE CustomStruct CustomStruct;
+
+void boxableStructsAvailable() {
+  [NSValue valueWithCGPoint:cg_point];
+  [NSValue valueWithCGVector:cg_vector];
+  [NSValue valueWithCGSize:cg_size];
+  [NSValue valueWithCGRect:cg_rect];
+  [NSValue valueWithCGAffineTransform:ca_affineTransform];
+  [NSValue valueWithUIEdgeInsets:ui_edgeInsets];
+  [NSValue valueWithUIOffset:ui_offset];
+
+  [NSValue valueWithRange:ns_range];
+  [NSValue valueWithCATransform3D:ca_transform3D];
+
+  [NSValue valueWithPoint:ns_point];
+  [NSValue valueWithSize:ns_size];
+  [NSValue valueWithRect:ns_rect];
+  [NSValue valueWithEdgeInsets:ns_edgeInsets];
+
+  [NSValue valueWithBytes:&customStruct objCType:@encode(CustomStruct)];
+  [NSValue valueWithBytes:&anotherCustomStruct objCType:@encode(AnotherCustomStruct)];
+  [NSValue valueWithRect:returnRect()];
+}
+
diff --git test/ARCMT/objcmt-objc-boxable.m.result test/ARCMT/objcmt-objc-boxable.m.result
new file mode 100644
index 0000000..4ea1564
--- /dev/null
+++ test/ARCMT/objcmt-objc-boxable.m.result
@@ -0,0 +1,176 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -mt-migrate-directory %t %s -x objective-c
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
+
+typedef unsigned long NSUInteger;
+typedef double CGFloat;
+
+typedef struct _NSRange {
+    NSUInteger location;
+    NSUInteger length;
+} NSRange;
+
+typedef struct CATransform3D
+{
+  CGFloat m11, m12, m13, m14;
+  CGFloat m21, m22, m23, m24;
+  CGFloat m31, m32, m33, m34;
+  CGFloat m41, m42, m43, m44;
+} CATransform3D;
+
+typedef struct CGPoint {
+    CGFloat x;
+    CGFloat y;
+} CGPoint;
+
+typedef struct CGSize {
+    CGFloat width;
+    CGFloat height;
+} CGSize;
+
+typedef struct CGVector {
+    CGFloat dx;
+    CGFloat dy;
+} CGVector;
+
+typedef struct CGRect {
+    CGPoint origin;
+    CGSize size;
+} CGRect;
+
+typedef struct UIEdgeInsets {
+    CGFloat top, left, bottom, right;
+} UIEdgeInsets;
+
+typedef struct UIOffset {
+    CGFloat horizontal, vertical;
+} UIOffset;
+
+typedef struct CGAffineTransform {
+  CGFloat a, b, c, d;
+  CGFloat tx, ty;
+} CGAffineTransform;
+
+typedef CGPoint NSPoint;
+typedef CGSize NSSize;
+typedef CGRect NSRect;
+
+typedef struct NSEdgeInsets {
+    CGFloat top;
+    CGFloat left;
+    CGFloat bottom;
+    CGFloat right;
+} NSEdgeInsets;
+
+typedef struct CustomStruct {
+    int dummy;
+} CustomStruct;
+
+typedef struct AnotherCustomStruct {
+    int dummy;
+} AnotherCustomStruct;
+
+extern CGRect returnRect();
+
+@interface NSObject @end
+
+@interface NSValue : NSObject
+
++ (NSValue *)valueWithCGPoint:(CGPoint)point;
++ (NSValue *)valueWithCGVector:(CGVector)vector;
++ (NSValue *)valueWithCGSize:(CGSize)size;
++ (NSValue *)valueWithCGRect:(CGRect)rect;
++ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
++ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
++ (NSValue *)valueWithUIOffset:(UIOffset)insets;
+
++ (NSValue *)valueWithRange:(NSRange)range;
++ (NSValue *)valueWithCATransform3D:(CATransform3D)t;
+
++ (NSValue *)valueWithPoint:(NSPoint)point;
++ (NSValue *)valueWithSize:(NSSize)size;
++ (NSValue *)valueWithRect:(NSRect)rect;
++ (NSValue *)valueWithEdgeInsets:(NSEdgeInsets)insets;
+
++ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;
+
+@end
+
+static CGPoint cg_point;
+static CGVector cg_vector;
+static CGSize cg_size;
+static CGRect cg_rect;
+static CGAffineTransform ca_affineTransform;
+static UIEdgeInsets ui_edgeInsets;
+static UIOffset ui_offset;
+static NSRange ns_range;
+static CATransform3D ca_transform3D;
+static NSPoint ns_point;
+static NSSize ns_size;
+static NSRect ns_rect;
+static NSEdgeInsets ns_edgeInsets;
+static CustomStruct customStruct;
+static AnotherCustomStruct anotherCustomStruct;
+
+void noBoxableStructsAvailableYet() {
+  [NSValue valueWithCGPoint:cg_point];
+  [NSValue valueWithCGVector:cg_vector];
+  [NSValue valueWithCGSize:cg_size];
+  [NSValue valueWithCGRect:cg_rect];
+  [NSValue valueWithCGAffineTransform:ca_affineTransform];
+  [NSValue valueWithUIEdgeInsets:ui_edgeInsets];
+  [NSValue valueWithUIOffset:ui_offset];
+
+  [NSValue valueWithRange:ns_range];
+  [NSValue valueWithCATransform3D:ca_transform3D];
+
+  [NSValue valueWithPoint:ns_point];
+  [NSValue valueWithSize:ns_size];
+  [NSValue valueWithRect:ns_rect];
+  [NSValue valueWithEdgeInsets:ns_edgeInsets];
+
+  [NSValue valueWithBytes:&customStruct objCType:@encode(CustomStruct)];
+  [NSValue valueWithBytes:&anotherCustomStruct objCType:@encode(AnotherCustomStruct)];
+  [NSValue valueWithRect:returnRect()];
+}
+
+#define BOXABLE __attribute__((objc_boxable))
+
+typedef struct BOXABLE _NSRange NSRange;
+typedef struct BOXABLE CATransform3D CATransform3D;
+typedef struct BOXABLE CGPoint CGPoint;
+typedef struct BOXABLE CGSize CGSize;
+typedef struct BOXABLE CGVector CGVector;
+typedef struct BOXABLE CGRect CGRect;
+typedef struct BOXABLE UIEdgeInsets UIEdgeInsets;
+typedef struct BOXABLE UIOffset UIOffset;
+typedef struct BOXABLE CGAffineTransform CGAffineTransform;
+typedef struct BOXABLE CGPoint NSPoint;
+typedef struct BOXABLE CGSize NSSize;
+typedef struct BOXABLE CGRect NSRect;
+typedef struct BOXABLE NSEdgeInsets NSEdgeInsets;
+typedef struct BOXABLE CustomStruct CustomStruct;
+
+void boxableStructsAvailable() {
+  @(cg_point);
+  @(cg_vector);
+  @(cg_size);
+  @(cg_rect);
+  @(ca_affineTransform);
+  @(ui_edgeInsets);
+  @(ui_offset);
+
+  @(ns_range);
+  @(ca_transform3D);
+
+  @(ns_point);
+  @(ns_size);
+  @(ns_rect);
+  @(ns_edgeInsets);
+
+  @(customStruct);
+  [NSValue valueWithBytes:&anotherCustomStruct objCType:@encode(AnotherCustomStruct)];
+  @(returnRect());
+}
+
