diff --git a/doc/snippets/Microsoft.Data/SqlDbTypeExtensions.xml b/doc/snippets/Microsoft.Data/SqlDbTypeExtensions.xml
new file mode 100644
index 0000000000..a3d03229f5
--- /dev/null
+++ b/doc/snippets/Microsoft.Data/SqlDbTypeExtensions.xml
@@ -0,0 +1,24 @@
+
+
+  
+    
+      Extensions for SqlDbType.
+      
+        
+           class provides  enums which will be added. These are meant to be used by applications which cannot leverage the enums in  available in newer .NET runtime versions.
+
+]]>
+        
+      
+    
+    
+      Gets the  enum value for the JSON datatype.
+      
+         enum value for JSON datatype.
+      
+    
+  
+
diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln
index f7efd31443..88d02dee48 100644
--- a/src/Microsoft.Data.SqlClient.sln
+++ b/src/Microsoft.Data.SqlClient.sln
@@ -73,6 +73,7 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data", "Microsoft.Data", "{908C7DD3-C999-40A6-9433-9F5ACA7C36F5}"
 	ProjectSection(SolutionItems) = preProject
 		..\doc\snippets\Microsoft.Data\OperationAbortedException.xml = ..\doc\snippets\Microsoft.Data\OperationAbortedException.xml
+		..\doc\snippets\Microsoft.Data\SqlDbTypeExtensions.xml = ..\doc\snippets\Microsoft.Data\SqlDbTypeExtensions.xml
 	EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.Sql", "Microsoft.Data.Sql", "{0CE216CE-8072-4985-B248-61F0D0BE9C2E}"
diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
index 5dfbf8af3f..cc836fa92f 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
@@ -5,8 +5,6 @@
 // NOTE: The current Microsoft.VSDesigner editor attributes are implemented for System.Data.SqlClient, and are not publicly available.
 // New attributes that are designed to work with Microsoft.Data.SqlClient and are publicly documented should be included in future.
 
-using System;
-
 [assembly: System.CLSCompliant(true)]
 namespace Microsoft.Data
 {
@@ -15,7 +13,15 @@ public sealed partial class OperationAbortedException : System.SystemException
     {
         internal OperationAbortedException() { }
     }
+
+    /// 
+    public static class SqlDbTypeExtensions
+    {
+        /// 
+        public const System.Data.SqlDbType Json = (System.Data.SqlDbType)35;
+    }
 }
+
 namespace Microsoft.Data.Sql
 {
     /// 
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index b9f6de4113..3bc178e7ae 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -962,7 +962,7 @@
   
   
     
-    
+    
     
     
     
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs
index 91d6e3e744..01e693ac50 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs
@@ -6466,7 +6466,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete
                     paramList.Append(size);
                     paramList.Append(')');
                 }
-                else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt))
+                else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt) && (mt.SqlDbType != SqlDbTypeExtensions.Json))
                 {
                     paramList.Append("(max) ");
                 }
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
index edeecb6c9f..7cefa4c2ec 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -5174,7 +5174,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Sql
             }
 
             // read the collation for 7.x servers
-            if (col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE))
+            if (col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE) && ((tdsType != TdsEnums.SQLJSON)))
             {
                 result = TryProcessCollation(stateObj, out col.collation);
                 if (result != TdsOperationStatus.Done)
@@ -5952,6 +5952,7 @@ private TdsOperationStatus TryReadSqlStringValue(SqlBuffer value, byte type, int
                 case TdsEnums.SQLVARCHAR:
                 case TdsEnums.SQLBIGVARCHAR:
                 case TdsEnums.SQLTEXT:
+                case TdsEnums.SQLJSON:
                     // If bigvarchar(max), we only read the first chunk here,
                     // expecting the caller to read the rest
                     if (encoding == null)
@@ -6420,6 +6421,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md,
                 case TdsEnums.SQLNCHAR:
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
+                case TdsEnums.SQLJSON:
                     result = TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj);
                     if (result != TdsOperationStatus.Done)
                     {
@@ -7957,6 +7959,7 @@ internal TdsOperationStatus TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserS
                              colmeta.tdsType == TdsEnums.SQLBIGVARCHAR ||
                              colmeta.tdsType == TdsEnums.SQLBIGVARBINARY ||
                              colmeta.tdsType == TdsEnums.SQLNVARCHAR ||
+                             colmeta.tdsType == TdsEnums.SQLJSON ||
                              // Large UDTs is WinFS-only
                              colmeta.tdsType == TdsEnums.SQLUDT,
                              "GetDataLength:Invalid streaming datatype");
@@ -9817,7 +9820,7 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet
                 }
                 else if (mt.IsPlp)
                 {
-                    if (mt.SqlDbType != SqlDbType.Xml)
+                    if (mt.SqlDbType != SqlDbType.Xml && mt.SqlDbType != SqlDbTypeExtensions.Json)
                         WriteShort(TdsEnums.SQL_USHORTVARMAXLEN, stateObj);
                 }
                 else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date))
@@ -9857,53 +9860,56 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet
 
             // write out collation or xml metadata
 
-            if (_is2005 && (mt.SqlDbType == SqlDbType.Xml))
+            if ((mt.SqlDbType == SqlDbType.Xml || mt.SqlDbType == SqlDbTypeExtensions.Json))
             {
-                if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) ||
-                    !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) ||
-                    !string.IsNullOrEmpty(param.XmlSchemaCollectionName))
+                if (mt.SqlDbType == SqlDbType.Xml)
                 {
-                    stateObj.WriteByte(1);  //Schema present flag
-
-                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase))
+                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) ||
+                        !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) ||
+                        !string.IsNullOrEmpty(param.XmlSchemaCollectionName))
                     {
-                        tempLen = (param.XmlSchemaCollectionDatabase).Length;
-                        stateObj.WriteByte((byte)(tempLen));
-                        WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj);
-                    }
-                    else
-                    {
-                        stateObj.WriteByte(0);       // No dbname
-                    }
+                        stateObj.WriteByte(1);   //Schema present flag
 
-                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema))
-                    {
-                        tempLen = (param.XmlSchemaCollectionOwningSchema).Length;
-                        stateObj.WriteByte((byte)(tempLen));
-                        WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj);
-                    }
-                    else
-                    {
-                        stateObj.WriteByte(0);      // no xml schema name
-                    }
+                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase))
+                        {
+                            tempLen = (param.XmlSchemaCollectionDatabase).Length;
+                            stateObj.WriteByte((byte)(tempLen));
+                            WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj);
+                        }
+                        else
+                        {
+                            stateObj.WriteByte(0);       // No dbname
+                        }
+
+                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema))
+                        {
+                            tempLen = (param.XmlSchemaCollectionOwningSchema).Length;
+                            stateObj.WriteByte((byte)(tempLen));
+                            WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj);
+                        }
+                        else
+                        {
+                            stateObj.WriteByte(0);      // no xml schema name
+                        }
+                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName))
+                        {
+                            tempLen = (param.XmlSchemaCollectionName).Length;
+                            WriteShort((short)(tempLen), stateObj);
+                            WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj);
+                        }
+                        else
+                        {
+                            WriteShort(0, stateObj);       // No xml schema collection name
+                        }
 
-                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName))
-                    {
-                        tempLen = (param.XmlSchemaCollectionName).Length;
-                        WriteShort((short)(tempLen), stateObj);
-                        WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj);
                     }
                     else
                     {
-                        WriteShort(0, stateObj);       // No xml schema collection name
+                        stateObj.WriteByte(0);       // No schema
                     }
                 }
-                else
-                {
-                    stateObj.WriteByte(0);       // No schema
-                }
             }
-            else if (mt.IsCharType)
+            else if (mt.IsCharType && mt.SqlDbType != SqlDbTypeExtensions.Json)
             {
                 // if it is not supplied, simply write out our default collation, otherwise, write out the one attached to the parameter
                 SqlCollation outCollation = (param.Collation != null) ? param.Collation : _defaultCollation;
@@ -11478,10 +11484,18 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
                 case TdsEnums.SQLXMLTYPE:
+                case TdsEnums.SQLJSON:
 
                     if (type.IsPlp)
                     {
-                        if (IsBOMNeeded(type, value))
+                        if (type.NullableType == TdsEnums.SQLJSON)
+                        {
+                            // TODO : Performance and BOM check. For more details see https://github.com/dotnet/SqlClient/issues/2852
+                            byte[] jsonAsBytes = Encoding.UTF8.GetBytes(value.ToString());
+                            WriteInt(jsonAsBytes.Length, stateObj);
+                            return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false);
+                        }
+                        else if (IsBOMNeeded(type, value))
                         {
                             WriteInt(actualLength + 2, stateObj);               // chunk length
                             WriteShort(TdsEnums.XMLUNICODEBOM, stateObj);
@@ -12128,6 +12142,7 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
                 case TdsEnums.SQLXMLTYPE:
+                case TdsEnums.SQLJSON: 
                     {
                         Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader");
                         Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string");
@@ -12149,7 +12164,14 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int
                         {
                             if (type.IsPlp)
                             {
-                                if (IsBOMNeeded(type, value))
+                                if (type.NullableType == TdsEnums.SQLJSON)
+                                {
+                                    // TODO : Performance and BOM check. Saurabh 
+                                    byte[] jsonAsBytes = Encoding.UTF8.GetBytes((string)value);
+                                    WriteInt(jsonAsBytes.Length, stateObj);
+                                    return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false);
+                                }
+                                else if (IsBOMNeeded(type, value))
                                 {
                                     WriteInt(actualLength + 2, stateObj);               // chunk length
                                     WriteShort(TdsEnums.XMLUNICODEBOM, stateObj);
@@ -12655,7 +12677,7 @@ internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsPars
                         WriteInt(unchecked((int)TdsEnums.VARLONGNULL), stateObj);
                     }
                 }
-                else if (type.NullableType == TdsEnums.SQLXMLTYPE || unknownLength)
+                else if (type.NullableType is TdsEnums.SQLXMLTYPE or TdsEnums.SQLJSON || unknownLength)
                 {
                     WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj);
                 }
diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
index d8bbb83106..421dc60d67 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs
@@ -18,7 +18,15 @@ internal OperationAbortedException() { }
         private OperationAbortedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
 
     }
+
+    /// 
+    public static class SqlDbTypeExtensions
+    {
+        /// 
+        public const System.Data.SqlDbType Json = (System.Data.SqlDbType)35;
+    }
 }
+
 namespace Microsoft.Data.Sql
 {
     /// 
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 730a747261..3e0139f31b 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -766,7 +766,7 @@
     
   
   
-    
+    
     
       $(SystemTextEncodingsWebVersion)
     
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
index ba860f106f..6745a0b56a 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
@@ -7173,7 +7173,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete
                     paramList.Append(size);
                     paramList.Append(')');
                 }
-                else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt))
+                else if (mt.IsPlp && (mt.SqlDbType != SqlDbType.Xml) && (mt.SqlDbType != SqlDbType.Udt) && (mt.SqlDbType != SqlDbTypeExtensions.Json))
                 {
                     paramList.Append("(max) ");
                 }
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
index f9b1306e42..4fd8ab7c68 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -5874,7 +5874,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Sql
             }
 
             // read the collation for 7.x servers
-            if (_is2000 && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE))
+            if (_is2000 && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE) && (tdsType != TdsEnums.SQLJSON))
             {
                 result = TryProcessCollation(stateObj, out col.collation);
                 if (result != TdsOperationStatus.Done)
@@ -6801,6 +6801,7 @@ private TdsOperationStatus TryReadSqlStringValue(SqlBuffer value, byte type, int
                 case TdsEnums.SQLVARCHAR:
                 case TdsEnums.SQLBIGVARCHAR:
                 case TdsEnums.SQLTEXT:
+                case TdsEnums.SQLJSON:
                     // If bigvarchar(max), we only read the first chunk here,
                     // expecting the caller to read the rest
                     if (encoding == null)
@@ -7251,6 +7252,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
                 case TdsEnums.SQLNCHAR:
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
+                case TdsEnums.SQLJSON:
                     result = TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj);
                     if (result != TdsOperationStatus.Done)
                     {
@@ -8775,6 +8777,7 @@ internal TdsOperationStatus TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserS
                              colmeta.tdsType == TdsEnums.SQLBIGVARCHAR ||
                              colmeta.tdsType == TdsEnums.SQLBIGVARBINARY ||
                              colmeta.tdsType == TdsEnums.SQLNVARCHAR ||
+                             colmeta.tdsType == TdsEnums.SQLJSON ||
                              // Large UDTs is WinFS-only
                              colmeta.tdsType == TdsEnums.SQLUDT,
                              "GetDataLength:Invalid streaming datatype");
@@ -10573,7 +10576,7 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout
                                 }
                                 else if (mt.IsPlp)
                                 {
-                                    if (mt.SqlDbType != SqlDbType.Xml)
+                                    if (mt.SqlDbType != SqlDbType.Xml && mt.SqlDbType != SqlDbTypeExtensions.Json)
                                         WriteShort(TdsEnums.SQL_USHORTVARMAXLEN, stateObj);
                                 }
                                 else if ((!mt.IsVarTime) && (mt.SqlDbType != SqlDbType.Date))
@@ -10614,53 +10617,56 @@ internal Task TdsExecuteRPC(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout
 
                             // write out collation or xml metadata
 
-                            if (_is2005 && (mt.SqlDbType == SqlDbType.Xml))
+                            if ((mt.SqlDbType == SqlDbType.Xml || mt.SqlDbType == SqlDbTypeExtensions.Json))
                             {
-                                if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) ||
-                                    !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) ||
-                                    !string.IsNullOrEmpty(param.XmlSchemaCollectionName))
+                                if (mt.SqlDbType == SqlDbType.Xml)
                                 {
-                                    stateObj.WriteByte(1);   //Schema present flag
-
-                                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase))
+                                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase) ||
+                                        !string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema) ||
+                                        !string.IsNullOrEmpty(param.XmlSchemaCollectionName))
                                     {
-                                        tempLen = (param.XmlSchemaCollectionDatabase).Length;
-                                        stateObj.WriteByte((byte)(tempLen));
-                                        WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj);
-                                    }
-                                    else
-                                    {
-                                        stateObj.WriteByte(0);       // No dbname
-                                    }
+                                        stateObj.WriteByte(1);   //Schema present flag
+
+                                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionDatabase))
+                                        {
+                                            tempLen = (param.XmlSchemaCollectionDatabase).Length;
+                                            stateObj.WriteByte((byte)(tempLen));
+                                            WriteString(param.XmlSchemaCollectionDatabase, tempLen, 0, stateObj);
+                                        }
+                                        else
+                                        {
+                                            stateObj.WriteByte(0);       // No dbname
+                                        }
+
+                                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema))
+                                        {
+                                            tempLen = (param.XmlSchemaCollectionOwningSchema).Length;
+                                            stateObj.WriteByte((byte)(tempLen));
+                                            WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj);
+                                        }
+                                        else
+                                        {
+                                            stateObj.WriteByte(0);      // no xml schema name
+                                        }
+                                        if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName))
+                                        {
+                                            tempLen = (param.XmlSchemaCollectionName).Length;
+                                            WriteShort((short)(tempLen), stateObj);
+                                            WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj);
+                                        }
+                                        else
+                                        {
+                                            WriteShort(0, stateObj);       // No xml schema collection name
+                                        }
 
-                                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionOwningSchema))
-                                    {
-                                        tempLen = (param.XmlSchemaCollectionOwningSchema).Length;
-                                        stateObj.WriteByte((byte)(tempLen));
-                                        WriteString(param.XmlSchemaCollectionOwningSchema, tempLen, 0, stateObj);
-                                    }
-                                    else
-                                    {
-                                        stateObj.WriteByte(0);      // no xml schema name
-                                    }
-                                    if (!string.IsNullOrEmpty(param.XmlSchemaCollectionName))
-                                    {
-                                        tempLen = (param.XmlSchemaCollectionName).Length;
-                                        WriteShort((short)(tempLen), stateObj);
-                                        WriteString(param.XmlSchemaCollectionName, tempLen, 0, stateObj);
                                     }
                                     else
                                     {
-                                        WriteShort(0, stateObj);       // No xml schema collection name
+                                        stateObj.WriteByte(0);       // No schema
                                     }
-
-                                }
-                                else
-                                {
-                                    stateObj.WriteByte(0);       // No schema
                                 }
                             }
-                            else if (_is2000 && mt.IsCharType)
+                            else if (mt.IsCharType && mt.SqlDbType != SqlDbTypeExtensions.Json)
                             {
                                 // if it is not supplied, simply write out our default collation, otherwise, write out the one attached to the parameter
                                 SqlCollation outCollation = (param.Collation != null) ? param.Collation : _defaultCollation;
@@ -12430,10 +12436,18 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
                 case TdsEnums.SQLXMLTYPE:
+                case TdsEnums.SQLJSON:
 
                     if (type.IsPlp)
                     {
-                        if (IsBOMNeeded(type, value))
+                        if (type.NullableType == TdsEnums.SQLJSON)
+                        {
+                            // TODO : Performance and BOM check. For more details see https://github.com/dotnet/SqlClient/issues/2852
+                            byte[] jsonAsBytes = Encoding.UTF8.GetBytes(value.ToString());
+                            WriteInt(jsonAsBytes.Length, stateObj);
+                            return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false);
+                        }
+                        else if (IsBOMNeeded(type, value))
                         {
                             WriteInt(actualLength + 2, stateObj);               // chunk length
                             WriteShort(TdsEnums.XMLUNICODEBOM, stateObj);
@@ -13122,6 +13136,7 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int
                 case TdsEnums.SQLNVARCHAR:
                 case TdsEnums.SQLNTEXT:
                 case TdsEnums.SQLXMLTYPE:
+                case TdsEnums.SQLJSON:
                     {
                         Debug.Assert(!isDataFeed || (value is TextDataFeed || value is XmlDataFeed), "Value must be a TextReader or XmlReader");
                         Debug.Assert(isDataFeed || (value is string || value is byte[]), "Value is a byte array or string");
@@ -13143,7 +13158,14 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int
                         {
                             if (type.IsPlp)
                             {
-                                if (IsBOMNeeded(type, value))
+                                if (type.NullableType == TdsEnums.SQLJSON)
+                                {
+                                    // TODO : Performance and BOM check. Saurabh 
+                                    byte[] jsonAsBytes = Encoding.UTF8.GetBytes((string)value);
+                                    WriteInt(jsonAsBytes.Length, stateObj);
+                                    return stateObj.WriteByteArray(jsonAsBytes, jsonAsBytes.Length, 0, canAccumulate: false);
+                                }
+                                else if (IsBOMNeeded(type, value))
                                 {
                                     WriteInt(actualLength + 2, stateObj);               // chunk length
                                     WriteShort(TdsEnums.XMLUNICODEBOM, stateObj);
@@ -13652,7 +13674,7 @@ internal void WriteParameterVarLen(MetaType type, int size, bool isNull, TdsPars
                         WriteInt(unchecked((int)TdsEnums.VARLONGNULL), stateObj);
                     }
                 }
-                else if (type.NullableType == TdsEnums.SQLXMLTYPE || unknownLength)
+                else if (type.NullableType is TdsEnums.SQLXMLTYPE or TdsEnums.SQLJSON || unknownLength)
                 {
                     WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj);
                 }
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs
index 86b9656684..0f8da0c874 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs
@@ -226,6 +226,8 @@ internal static MetaType GetMetaTypeFromSqlDbType(SqlDbType target, bool isMulti
                     return MetaXml;
                 case SqlDbType.Udt:
                     return MetaUdt;
+                case SqlDbTypeExtensions.Json:
+                    return s_MetaJson;
                 case SqlDbType.Structured:
                     if (isMultiValued)
                     {
@@ -862,6 +864,8 @@ internal static MetaType GetSqlDataType(int tdsType, uint userType, int length)
                     return s_metaDateTime2;
                 case TdsEnums.SQLDATETIMEOFFSET:
                     return MetaDateTimeOffset;
+                case TdsEnums.SQLJSON:
+                    return s_MetaJson;
 
                 case TdsEnums.SQLVOID:
                 default:
@@ -968,6 +972,8 @@ internal static string GetStringFromXml(XmlReader xmlreader)
 
         internal static readonly MetaType MetaDateTimeOffset = new(255, 7, -1, false, false, false, TdsEnums.SQLDATETIMEOFFSET, TdsEnums.SQLDATETIMEOFFSET, MetaTypeName.DATETIMEOFFSET, typeof(System.DateTimeOffset), typeof(System.DateTimeOffset), SqlDbType.DateTimeOffset, DbType.DateTimeOffset, 1);
 
+        internal static readonly MetaType s_MetaJson = new(255, 255, -1, false, true, true, TdsEnums.SQLJSON, TdsEnums.SQLJSON, MetaTypeName.JSON, typeof(string), typeof(string), SqlDbTypeExtensions.Json, DbType.String, 0);
+
         public static TdsDateTime FromDateTime(DateTime dateTime, byte cb)
         {
             SqlDateTime sqlDateTime;
@@ -1054,6 +1060,7 @@ private static class MetaTypeName
             public const string TIME = "time";
             public const string DATETIME2 = "datetime2";
             public const string DATETIMEOFFSET = "datetimeoffset";
+            public const string JSON = "json";
         }
     }
 
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs
index 034a2ac306..da214059a0 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs
@@ -1563,6 +1563,7 @@ internal int GetActualSize()
                         case SqlDbType.NVarChar:
                         case SqlDbType.NText:
                         case SqlDbType.Xml:
+                        case SqlDbTypeExtensions.Json:
                             {
                                 coercedSize = ((!HasFlag(SqlParameterFlags.IsNull)) && (!HasFlag(SqlParameterFlags.CoercedValueIsDataFeed))) ? StringSize(val, HasFlag(SqlParameterFlags.CoercedValueIsSqlType)) : 0;
                                 _actualSize = (ShouldSerializeSize() ? Size : 0);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
index 685002790c..8ae65384ef 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
@@ -490,6 +490,8 @@ public enum ActiveDirectoryWorkflow : byte
         public const int SQLDATETIME2 = 0x2a;
         public const int SQLDATETIMEOFFSET = 0x2b;
 
+        public const int SQLJSON = 0xF4;
+
         public const int DEFAULT_VARTIME_SCALE = 7;
 
         //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE,
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlDbTypeExtensions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlDbTypeExtensions.cs
index 18c53f428b..df7f597517 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlDbTypeExtensions.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlDbTypeExtensions.cs
@@ -6,14 +6,10 @@
 
 namespace Microsoft.Data
 {
-    /// 
-    /// Extensions for SqlDbType enum to enable its usage.
-    /// 
+    /// 
     public static class SqlDbTypeExtensions
     {
-        /// 
-        /// Represents the JSON Data type in SQL Server.
-        /// 
+        /// 
 #if NET9_0_OR_GREATER
         public const SqlDbType Json = SqlDbType.Json;
 #else
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
index 9e69b7a39f..9da517b8b6 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
@@ -94,6 +94,9 @@ public static class DataTestUtility
         //SQL Server EngineEdition
         private static string s_sqlServerEngineEdition;
 
+        // JSON Coloumn type
+        public static readonly bool IsJsonSupported = false;
+
         // Azure Synapse EngineEditionId == 6
         // More could be read at https://learn.microsoft.com/en-us/sql/t-sql/functions/serverproperty-transact-sql?view=sql-server-ver16#propertyname
         public static bool IsAzureSynapse
@@ -175,6 +178,7 @@ static DataTestUtility()
             ManagedIdentitySupported = c.ManagedIdentitySupported;
             IsManagedInstance = c.IsManagedInstance;
             AliasName = c.AliasName;
+            IsJsonSupported = c.IsJsonSupported;
 
             System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
 
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
index 0ec61b5420..7afb3c818c 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
@@ -291,6 +291,7 @@
     
     
     
+    
     
     
     
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs
new file mode 100644
index 0000000000..c8b3507b5d
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs
@@ -0,0 +1,295 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Data;
+using Microsoft.Data;
+using System.Data.Common;
+using System.Data.SqlTypes;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Microsoft.Data.SqlClient.ManualTesting.Tests
+{
+    public class JsonTest
+    {
+        private readonly ITestOutputHelper _output;
+
+        public JsonTest(ITestOutputHelper output)
+        {
+            _output = output;
+        }
+
+        private static readonly string jsonDataString = "[{\"name\":\"Dave\",\"skills\":[\"Python\"]},{\"name\":\"Ron\",\"surname\":\"Peter\"}]";
+
+        private void ValidateRowsAffected(int rowsAffected)
+        {
+            _output.WriteLine($"Rows affected: {rowsAffected}");
+            Assert.Equal(1, rowsAffected);
+        }
+
+        private void ValidateRows(SqlDataReader reader)
+        {
+            while (reader.Read())
+            {
+                string jsonData = reader.GetString(0);
+                _output.WriteLine(jsonData);
+                Assert.Equal(jsonDataString, jsonData);
+            }
+        }
+
+        private async Task ValidateRowsAsync(SqlDataReader reader)
+        {
+            while (await reader.ReadAsync())
+            {
+                string jsonData = reader.GetString(0);
+                _output.WriteLine(jsonData);
+                Assert.Equal(jsonDataString, jsonData);
+            }
+        }
+
+        private void ValidateSchema(SqlDataReader reader)
+        {
+            System.Collections.ObjectModel.ReadOnlyCollection schema = reader.GetColumnSchema();
+            foreach (DbColumn column in schema)
+            {
+                _output.WriteLine("Column Name is " + column.ColumnName);
+                _output.WriteLine("Column DataType is " + column?.DataType.ToString());
+                _output.WriteLine("Column DataTypeName is " + column.DataTypeName);
+                Assert.Equal("json", column.DataTypeName);
+            }
+        }
+
+        [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+        public void TestJsonWrite()
+        {       
+            string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+            string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_WriteTest");
+           
+            string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+            string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+            string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert;
+
+            using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+            {
+                connection.Open();
+
+                using (SqlCommand command = connection.CreateCommand())
+                {
+                    //Create Table
+                    command.CommandText = tableCreate;
+                    command.ExecuteNonQuery();
+
+                    //Create SP for writing json values
+                    command.CommandText = spCreate;
+                    command.ExecuteNonQuery();
+
+                    command.CommandText = tableInsert;
+                    var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                    command.Parameters.Add(parameter);
+
+                    //Test 1
+                    //Write json value using a parameterized query
+                    parameter.Value = jsonDataString;
+                    int rowsAffected = command.ExecuteNonQuery();
+                    ValidateRowsAffected(rowsAffected);
+
+                    //Test 2 
+                    //Write a SqlString type as json
+                    parameter.Value = new SqlString(jsonDataString);
+                    int rowsAffected2 = command.ExecuteNonQuery();
+                    ValidateRowsAffected(rowsAffected2);
+
+                    //Test 3
+                    //Write json value using SP
+                    using (SqlCommand command2 = connection.CreateCommand())
+                    {
+                        command2.CommandText = spName;
+                        command2.CommandType = CommandType.StoredProcedure;
+                        var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                        parameter2.Value = jsonDataString;
+                        command2.Parameters.Add(parameter2);
+                        int rowsAffected3 = command2.ExecuteNonQuery();
+                        ValidateRowsAffected(rowsAffected3);
+                    }
+
+                    DataTestUtility.DropTable(connection, tableName);
+                }
+            }
+        }
+
+        [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+        public async Task TestJsonWriteAsync()
+        {
+            string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+            string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_WriteTest");
+
+            string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+            string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+            string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert;
+
+            using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+            {
+                await connection.OpenAsync();
+
+                using (SqlCommand command = connection.CreateCommand())
+                {
+                    //Create Table
+                    command.CommandText = tableCreate;
+                    await command.ExecuteNonQueryAsync();
+
+                    //Create SP for writing json values
+                    command.CommandText = spCreate;
+                    await command.ExecuteNonQueryAsync();
+
+                    command.CommandText = tableInsert;
+                    var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                    command.Parameters.Add(parameter);
+
+                    //Test 1
+                    //Write json value using a parameterized query
+                    parameter.Value = jsonDataString;
+                    int rowsAffected = await command.ExecuteNonQueryAsync();
+                    ValidateRowsAffected(rowsAffected);
+
+                    //Test 2 
+                    //Write a SqlString type as json
+                    parameter.Value = new SqlString(jsonDataString);
+                    int rowsAffected2 = await command.ExecuteNonQueryAsync();
+                    ValidateRowsAffected(rowsAffected2);
+
+                    //Test 3
+                    //Write json value using SP
+                    using (SqlCommand command2 = connection.CreateCommand())
+                    {
+                        command2.CommandText = spName;
+                        command2.CommandType = CommandType.StoredProcedure;
+                        var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                        parameter2.Value = jsonDataString;
+                        command2.Parameters.Add(parameter2);
+                        int rowsAffected3 = await command.ExecuteNonQueryAsync();
+                        ValidateRowsAffected(rowsAffected3);
+                    }
+                }
+            }
+        }
+
+        [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+        public void TestJsonRead()
+        {
+            string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+            string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_ReadTest");
+
+            string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+            string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+            string tableRead = "SELECT * FROM " + tableName;
+            string spCreate = "CREATE PROCEDURE " + spName + "AS " + tableRead;
+
+            using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+            {
+                connection.Open();
+                using (SqlCommand command = connection.CreateCommand())
+                {
+                    //Create Table
+                    command.CommandText = tableCreate;
+                    command.ExecuteNonQuery();
+
+                    //Create SP for reading from json column
+                    command.CommandText = spCreate;
+                    command.ExecuteNonQuery();
+
+                    //Insert sample json data
+                    //This will be used for reading
+                    command.CommandText = tableInsert;
+                    var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                    parameter.Value = jsonDataString;
+                    command.Parameters.Add(parameter);
+                    command.ExecuteNonQuery();
+
+                    //Test 1
+                    //Read json value using query
+                    command.CommandText = tableRead;
+                    var reader = command.ExecuteReader();
+                    ValidateRows(reader);
+
+                    //Test 2
+                    //Read the column metadata
+                    ValidateSchema(reader);
+                    reader.Close();
+
+                    //Test 3
+                    //Read json value using SP
+                    using (SqlCommand command2 = connection.CreateCommand())
+                    {
+                        command2.CommandText = spName;
+                        command2.CommandType = CommandType.StoredProcedure;
+                        var reader2 = command2.ExecuteReader();
+                        ValidateRows(reader2);
+                        reader2.Close();
+                    }
+
+                    DataTestUtility.DropTable(connection, tableName);
+                }
+            }
+        }
+
+        [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+        public async Task TestJsonReadAsync()
+        {
+            string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+            string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_ReadTest");
+
+            string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+            string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+            string tableRead = "SELECT * FROM " + tableName;
+            string spCreate = "CREATE PROCEDURE " + spName + "AS " + tableRead;
+
+            using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+            {
+                await connection.OpenAsync();
+                using (SqlCommand command = connection.CreateCommand())
+                {
+                    //Create Table
+                    command.CommandText = tableCreate;
+                    await command.ExecuteNonQueryAsync();
+
+                    //Create SP for reading from json column
+                    command.CommandText = spCreate;
+                    await command.ExecuteNonQueryAsync();
+
+                    //Insert sample json data
+                    //This will be used for reading
+                    command.CommandText = tableInsert;
+                    var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+                    parameter.Value = jsonDataString;
+                    command.Parameters.Add(parameter);
+                    await command.ExecuteNonQueryAsync();
+
+                    //Test 1
+                    //Read json value using query
+                    command.CommandText = tableRead;
+                    var reader = await command.ExecuteReaderAsync();
+                    await ValidateRowsAsync(reader);
+
+                    //Test 2
+                    //Read the column metadata
+                    ValidateSchema(reader);
+                    reader.Close();
+
+                    //Test 3
+                    //Read json value using SP
+                    using (SqlCommand command2 = connection.CreateCommand())
+                    {
+                        command2.CommandText = spName;
+                        command2.CommandType = CommandType.StoredProcedure;
+                        var reader2 = await command2.ExecuteReaderAsync();
+                        await ValidateRowsAsync(reader2);
+                        reader2.Close();
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
index 3fbe8313ee..1b712ceaf5 100644
--- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
+++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
@@ -42,6 +42,7 @@ public class Config
         public string KerberosDomainUser = null;
         public bool IsManagedInstance = false;
         public string AliasName = null;
+        public bool IsJsonSupported = false;
         public static Config Load(string configPath = @"config.json")
         {
             try