diff --git a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
index 8ed048427..c629f78be 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiConstants.cs
@@ -700,6 +700,16 @@ public static class OpenApiConstants
         /// 
         public const string ComponentsSegment = "/components/";
 
+        /// 
+        /// Field: Null
+        /// 
+        public const string Null = "null";
+
+        /// 
+        /// Field: Nullable extension
+        /// 
+        public const string NullableExtension = "x-nullable";
+
         #region V2.0
 
         /// 
diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
index 25352086f..eda8249dc 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs
@@ -483,14 +483,7 @@ public void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
             writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (nodeWriter, s) => nodeWriter.WriteAny(s));
 
             // type
-            if (Type?.GetType() == typeof(string))
-            {
-                writer.WriteProperty(OpenApiConstants.Type, (string)Type);
-            }
-            else
-            {
-                writer.WriteOptionalCollection(OpenApiConstants.Type, (string[])Type, (w, s) => w.WriteRaw(s));
-            }
+            SerializeTypeProperty(Type, writer, version);
 
             // allOf
             writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV3(w));
@@ -533,7 +526,10 @@ public void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version,
             writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d));
 
             // nullable
-            writer.WriteProperty(OpenApiConstants.Nullable, Nullable, false);
+            if (version is OpenApiSpecVersion.OpenApi3_0)
+            {
+                writer.WriteProperty(OpenApiConstants.Nullable, Nullable, false);
+            }
 
             // discriminator
             writer.WriteOptionalObject(OpenApiConstants.Discriminator, Discriminator, (w, s) => s.SerializeAsV3(w));
@@ -670,7 +666,14 @@ internal void SerializeAsV2(
             writer.WriteStartObject();
 
             // type
-            writer.WriteProperty(OpenApiConstants.Type, (string)Type);
+            if (Type is string[] array)
+            {
+                DowncastTypeArrayToV2OrV3(array, writer, OpenApiSpecVersion.OpenApi2_0);
+            }
+            else 
+            {
+                writer.WriteProperty(OpenApiConstants.Type, (string)Type);
+            }
 
             // description
             writer.WriteProperty(OpenApiConstants.Description, Description);
@@ -799,6 +802,35 @@ internal void SerializeAsV2(
             writer.WriteEndObject();
         }
 
+        private void SerializeTypeProperty(object type, IOpenApiWriter writer, OpenApiSpecVersion version)
+        {
+            if (type?.GetType() == typeof(string))
+            {
+                // check whether nullable is true for upcasting purposes
+                if (Nullable || Extensions.ContainsKey(OpenApiConstants.NullableExtension))
+                {
+                    // create a new array and insert the type and "null" as values
+                    Type = new[] { (string)Type, OpenApiConstants.Null };
+                }
+                else
+                {
+                    writer.WriteProperty(OpenApiConstants.Type, (string)Type);
+                }
+            }
+            if (Type is string[] array)
+            {
+                // type
+                if (version is OpenApiSpecVersion.OpenApi3_0)
+                {
+                    DowncastTypeArrayToV2OrV3(array, writer, OpenApiSpecVersion.OpenApi3_0);
+                }
+                else
+                {
+                    writer.WriteOptionalCollection(OpenApiConstants.Type, (string[])Type, (w, s) => w.WriteRaw(s));
+                }
+            }
+        }
+
         private object DeepCloneType(object type)
         {
             if (type == null)
@@ -822,5 +854,38 @@ private object DeepCloneType(object type)
 
             return null;
         }
+
+        private void DowncastTypeArrayToV2OrV3(string[] array, IOpenApiWriter writer, OpenApiSpecVersion version)
+        {
+            /* If the array has one non-null value, emit Type as string
+            * If the array has one null value, emit x-nullable as true
+            * If the array has two values, one null and one non-null, emit Type as string and x-nullable as true
+            * If the array has more than two values or two non-null values, do not emit type
+            * */
+
+            var nullableProp = version.Equals(OpenApiSpecVersion.OpenApi2_0) 
+                ? OpenApiConstants.NullableExtension
+                : OpenApiConstants.Nullable;
+
+            if (array.Length is 1)
+            {
+                var value = array[0];
+                if (value is OpenApiConstants.Null)
+                {
+                    writer.WriteProperty(nullableProp, true);
+                }
+                else
+                {
+                    writer.WriteProperty(OpenApiConstants.Type, value);
+                }
+            }
+            else if (array.Length is 2 && array.Contains(OpenApiConstants.Null))
+            {
+                // Find the non-null value and write it out
+                var nonNullValue = array.First(v => v != OpenApiConstants.Null);
+                writer.WriteProperty(OpenApiConstants.Type, nonNullValue);
+                writer.WriteProperty(nullableProp, true);
+            }
+        }
     }
 }
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs
index f8d197170..7757c710f 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs
@@ -182,7 +182,22 @@ internal static partial class OpenApiV31Deserializer
             },
             {
                 "nullable",
-                (o, n, _) => o.Nullable = bool.Parse(n.GetScalarValue())
+                (o, n, _) => 
+                {
+                    var nullable = bool.Parse(n.GetScalarValue());
+                    if (nullable) // if nullable, convert type into an array of type(s) and null
+                    {
+                        if (o.Type is string[] typeArray)
+                        {
+                            var typeList = new List(typeArray) { OpenApiConstants.Null };
+                            o.Type = typeList.ToArray();
+                        }
+                        else if (o.Type is string typeString)
+                        {
+                            o.Type = new string[]{typeString, OpenApiConstants.Null};
+                        }
+                    }
+                }
             },
             {
                 "discriminator",
@@ -242,6 +257,13 @@ public static OpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocum
                 propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields);
             }
 
+            if (schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension))
+            {
+                var type = schema.Type;                
+                schema.Type = new string[] {(string)type, OpenApiConstants.Null};
+                schema.Extensions.Remove(OpenApiConstants.NullableExtension);
+            }
+
             return schema;
         }
     }
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
index af11245d4..cacb1ed86 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
@@ -1,13 +1,15 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT license. 
 
 using System.Collections.Generic;
+using System.IO;
 using System.Text.Json.Nodes;
 using FluentAssertions;
 using FluentAssertions.Equivalency;
-using Microsoft.OpenApi.Any;
 using Microsoft.OpenApi.Models;
 using Microsoft.OpenApi.Reader;
+using Microsoft.OpenApi.Tests;
+using Microsoft.OpenApi.Writers;
 using Xunit;
 
 namespace Microsoft.OpenApi.Readers.Tests.V31Tests
@@ -289,5 +291,118 @@ public void CloningSchemaWithExamplesAndEnumsShouldSucceed()
             clone.Examples.Should().NotBeEquivalentTo(schema.Examples);
             clone.Default.Should().NotBeEquivalentTo(schema.Default);
         }
+
+        [Fact]
+        public void SerializeV31SchemaWithMultipleTypesAsV3Works()
+        {
+            // Arrange
+            var expected = @"type: string
+nullable: true";
+
+            var path = Path.Combine(SampleFolderPath, "schemaWithTypeArray.yaml");
+
+            // Act
+            var schema = OpenApiModelFactory.Load(path, OpenApiSpecVersion.OpenApi3_1, out _);
+
+            var writer = new StringWriter();
+            schema.SerializeAsV3(new OpenApiYamlWriter(writer));
+            var schema1String = writer.ToString();
+
+            schema1String.MakeLineBreaksEnvironmentNeutral().Should().Be(expected.MakeLineBreaksEnvironmentNeutral());
+        }
+
+        [Fact]
+        public void SerializeV31SchemaWithMultipleTypesAsV2Works()
+        {
+            // Arrange
+            var expected = @"type: string
+x-nullable: true";
+
+            var path = Path.Combine(SampleFolderPath, "schemaWithTypeArray.yaml");
+
+            // Act
+            var schema = OpenApiModelFactory.Load(path, OpenApiSpecVersion.OpenApi3_1, out _);
+
+            var writer = new StringWriter();
+            schema.SerializeAsV2(new OpenApiYamlWriter(writer));
+            var schema1String = writer.ToString();
+
+            schema1String.MakeLineBreaksEnvironmentNeutral().Should().Be(expected.MakeLineBreaksEnvironmentNeutral());
+        }
+
+        [Fact]
+        public void SerializeV3SchemaWithNullableAsV31Works()
+        {
+            // Arrange
+            var expected = @"type:
+  - string
+  - null";
+
+            var path = Path.Combine(SampleFolderPath, "schemaWithNullable.yaml");
+
+            // Act
+            var schema = OpenApiModelFactory.Load(path, OpenApiSpecVersion.OpenApi3_0, out _);
+
+            var writer = new StringWriter();
+            schema.SerializeAsV31(new OpenApiYamlWriter(writer));
+            var schemaString = writer.ToString();
+
+            schemaString.MakeLineBreaksEnvironmentNeutral().Should().Be(expected.MakeLineBreaksEnvironmentNeutral());
+        }
+
+        [Fact]
+        public void SerializeV2SchemaWithNullableExtensionAsV31Works()
+        {
+            // Arrange
+            var expected = @"type:
+  - string
+  - null
+x-nullable: true";
+
+            var path = Path.Combine(SampleFolderPath, "schemaWithNullableExtension.yaml");
+
+            // Act
+            var schema = OpenApiModelFactory.Load(path, OpenApiSpecVersion.OpenApi2_0, out _);
+
+            var writer = new StringWriter();
+            schema.SerializeAsV31(new OpenApiYamlWriter(writer));
+            var schemaString = writer.ToString();
+
+            schemaString.MakeLineBreaksEnvironmentNeutral().Should().Be(expected.MakeLineBreaksEnvironmentNeutral());
+        }
+
+        [Fact]
+        public void SerializeSchemaWithTypeArrayAndNullableDoesntEmitType()
+        {
+            var input = @"type:
+- ""string""
+- ""int""
+nullable: true";
+
+            var expected = @"{ }";
+
+            var schema = OpenApiModelFactory.Parse(input, OpenApiSpecVersion.OpenApi3_1, out _, "yaml");
+
+            var writer = new StringWriter();
+            schema.SerializeAsV2(new OpenApiYamlWriter(writer));
+            var schemaString = writer.ToString();
+
+            schemaString.MakeLineBreaksEnvironmentNeutral().Should().Be(expected.MakeLineBreaksEnvironmentNeutral()); 
+        }
+
+        [Theory]
+        [InlineData("schemaWithNullable.yaml")]
+        [InlineData("schemaWithNullableExtension.yaml")]
+        public void LoadSchemaWithNullableExtensionAsV31Works(string filePath)
+        {
+            // Arrange
+            var path = Path.Combine(SampleFolderPath, filePath);
+
+            // Act
+            var schema = OpenApiModelFactory.Load(path, OpenApiSpecVersion.OpenApi3_1, out _);
+
+            // Assert
+            schema.Type.Should().BeEquivalentTo(new string[] { "string", "null" });
+        }
     }
 }
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullable.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullable.yaml
new file mode 100644
index 000000000..913c768d3
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullable.yaml
@@ -0,0 +1,2 @@
+type: string
+nullable: true
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullableExtension.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullableExtension.yaml
new file mode 100644
index 000000000..e9bfbd513
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithNullableExtension.yaml
@@ -0,0 +1,2 @@
+type: string
+x-nullable: true
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithTypeArray.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithTypeArray.yaml
new file mode 100644
index 000000000..38ac212be
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiSchema/schemaWithTypeArray.yaml
@@ -0,0 +1,3 @@
+type:
+- "string"
+- "null"
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
index 7eb01a70c..18954d3f7 100755
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -437,7 +437,9 @@ namespace Microsoft.OpenApi.Models
         public const string Name = "name";
         public const string Namespace = "namespace";
         public const string Not = "not";
+        public const string Null = "null";
         public const string Nullable = "nullable";
+        public const string NullableExtension = "x-nullable";
         public const string OneOf = "oneOf";
         public const string OpenApi = "openapi";
         public const string OpenIdConnectUrl = "openIdConnectUrl";