diff --git a/Lib/ufo2ft/constants.py b/Lib/ufo2ft/constants.py
index 662ed16..0028eac 100644
--- a/Lib/ufo2ft/constants.py
+++ b/Lib/ufo2ft/constants.py
@@ -21,5 +21,6 @@ COLOR_PALETTES_KEY = UFO2FT_PREFIX + "colorPalettes"
 COLOR_LAYER_MAPPING_KEY = UFO2FT_PREFIX + "colorLayerMapping"
 
 OPENTYPE_CATEGORIES_KEY = "public.openTypeCategories"
+OPENTYPE_META_KEY = "public.openTypeMeta"
 
 UNICODE_VARIATION_SEQUENCES_KEY = "public.unicodeVariationSequences"
diff --git a/Lib/ufo2ft/outlineCompiler.py b/Lib/ufo2ft/outlineCompiler.py
index c3c2d1b..f3aff92 100644
--- a/Lib/ufo2ft/outlineCompiler.py
+++ b/Lib/ufo2ft/outlineCompiler.py
@@ -27,6 +27,7 @@ from fontTools.ttLib.tables.O_S_2f_2 import Panose
 from ufo2ft.constants import (
     COLOR_LAYERS_KEY,
     COLOR_PALETTES_KEY,
+    OPENTYPE_META_KEY,
     UNICODE_VARIATION_SEQUENCES_KEY,
 )
 from ufo2ft.errors import InvalidFontData
@@ -86,6 +87,7 @@ class BaseOutlineCompiler:
             "vhea",
             "COLR",
             "CPAL",
+            "meta",
         ]
     )
 
@@ -135,6 +137,7 @@ class BaseOutlineCompiler:
         self.colorLayers = (
             COLOR_LAYERS_KEY in self.ufo.lib and COLOR_PALETTES_KEY in self.ufo.lib
         )
+        self.meta = OPENTYPE_META_KEY in self.ufo.lib
 
         # write the glyph order
         self.otf.setGlyphOrder(self.glyphOrder)
@@ -154,6 +157,8 @@ class BaseOutlineCompiler:
         if self.colorLayers:
             self.setupTable_COLR()
             self.setupTable_CPAL()
+        if self.meta:
+            self.setupTable_meta()
         self.setupOtherTables()
         self.importTTX()
 
@@ -978,6 +983,45 @@ class BaseOutlineCompiler:
         except ColorLibError as e:
             raise InvalidFontData("Failed to build CPAL table") from e
 
+    def setupTable_meta(self):
+        """
+        Make the meta table.
+
+        ***This should not be called externally.** Sublcasses
+        may override or supplement this method to handle the
+        table creation in a different way if desired.
+        """
+        if "meta" not in self.tables:
+            return
+
+        font = self.ufo
+        self.otf["meta"] = meta = newTable("meta")
+        ufo_meta = font.lib.get(OPENTYPE_META_KEY)
+        for key, value in ufo_meta.items():
+            if key in ["dlng", "slng"]:
+                if not isinstance(value, list) or not all(
+                    isinstance(string, str) for string in value
+                ):
+                    raise TypeError(
+                        f"public.openTypeMeta '{key}' value should "
+                        "be a list of strings"
+                    )
+                meta.data[key] = ",".join(value)
+            elif key in ["appl", "bild"]:
+                if not isinstance(value, bytes):
+                    raise TypeError(
+                        f"public.openTypeMeta '{key}' value should be bytes."
+                    )
+                meta.data[key] = value
+            elif isinstance(value, bytes):
+                meta.data[key] = value
+            elif isinstance(value, str):
+                meta.data[key] = value.encode("utf-8")
+            else:
+                raise TypeError(
+                    f"public.openTypeMeta '{key}' value should be bytes or a string."
+                )
+
     def setupOtherTables(self):
         """
         Make the other tables. The default implementation does nothing.

diff --git a/tests/outlineCompiler_test.py b/tests/outlineCompiler_test.py
index 03ee1d9..cc9abc4 100644
--- a/tests/outlineCompiler_test.py
+++ b/tests/outlineCompiler_test.py
@@ -205,6 +205,29 @@ class OutlineTTFCompilerTest:
         assert endPts == [4]
         assert list(flags) == [0, 0, 0, 0, 1]
 
+    def test_setupTable_meta(self, testufo):
+        testufo.lib["public.openTypeMeta"] = {
+            "appl": b"BEEF",
+            "bild": b"AAAA",
+            "dlng": ["en-Latn", "nl-Latn"],
+            "slng": ["Latn"],
+            "PRIB": b"Some private bytes",
+            "PRIA": "Some private ascii string",
+            "PRIU": "Some private unicode string…",
+        }
+
+        compiler = OutlineTTFCompiler(testufo)
+        ttFont = compiler.compile()
+        meta = ttFont["meta"]
+
+        assert meta.data["appl"] == b"BEEF"
+        assert meta.data["bild"] == b"AAAA"
+        assert meta.data["dlng"] == "en-Latn,nl-Latn"
+        assert meta.data["slng"] == "Latn"
+        assert meta.data["PRIB"] == b"Some private bytes"
+        assert meta.data["PRIA"] == b"Some private ascii string"
+        assert meta.data["PRIU"] == "Some private unicode string…".encode("utf-8")
+
 
 class OutlineOTFCompilerTest:
     def test_setupTable_CFF_all_blues_defined(self, testufo):

Add support for dlng and slng
Now that UFO3 spec includes `public.openTypeMeta` in [lib.plist](http://unifiedfontobject.org/versions/ufo3/lib.plist/), could we get support for `dlng` and `slng` [metadata tags](https://docs.microsoft.com/en-us/typography/opentype/spec/meta#metadata-tags)?
tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_meta[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_meta[ufoLib2]
tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_with_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_without_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_empty_gasp[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_makeGlyphsBoundingBoxes[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_None[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_importTTX[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_no_contour_glyphs[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_os2_no_widths[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_missing_component[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_contour_starts_with_offcurve_point[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_all_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_some_blues_defined[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_all[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_none[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_some[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_optimize[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_optimize[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes_floats[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_importTTX[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_no_contour_glyphs[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_and_nominal_widths[defcon] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_but_no_nominal_widths[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_original_glyph_order[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_tweaked_glyph_order[defcon] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_strange_glyph_order[defcon] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[defcon-useProductionNames] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[defcon-Don't tests/outlineCompiler_test.py::NamesTest::test_compile_with_production_names[defcon] tests/outlineCompiler_test.py::NamesTest::test_postprocess_production_names_no_notdef[defcon] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[defcon-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[defcon-True] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[defcon-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[defcon-True] tests/outlineCompiler_test.py::NamesTest::test_warn_name_exceeds_max_length[defcon] tests/outlineCompiler_test.py::NamesTest::test_duplicate_glyph_names[defcon] tests/outlineCompiler_test.py::NamesTest::test_too_long_production_name[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal[defcon] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_raw[defcon] tests/outlineCompiler_test.py::CmapTest::test_cmap_BMP[defcon] tests/outlineCompiler_test.py::CmapTest::test_cmap_nonBMP_with_UVS[defcon] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes0-expected0] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes1-expected1] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes2-expected2] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes3-expected3] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes4-expected4] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes5-expected5] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes6-expected6] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes7-expected7] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes8-expected8] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes9-expected9] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes10-expected10] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes11-expected11] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes12-expected12] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes13-expected13] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes14-expected14] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes15-expected15] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes16-expected16] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes17-expected17] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes18-expected18] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes19-expected19] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes20-expected20] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes21-expected21] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes22-expected22] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes23-expected23] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes24-expected24] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes25-expected25] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes26-expected26] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes27-expected27] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes28-expected28] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes29-expected29] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes30-expected30] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes31-expected31] tests/outlineCompiler_test.py::test_calcCodePageRanges[defcon-unicodes32-expected32] tests/outlineCompiler_test.py::test_custom_layer_compilation[defcon] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable[defcon] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[defcon-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[defcon-inplace] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[defcon-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[defcon-inplace] tests/outlineCompiler_test.py::test_compilation_from_ds_missing_source_font[defcon] tests/outlineCompiler_test.py::test_compile_empty_ufo[defcon] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_setupTable_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_with_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_without_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_compile_empty_gasp[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_makeGlyphsBoundingBoxes[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_autoUseMyMetrics_None[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_importTTX[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_no_contour_glyphs[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_os2_no_widths[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_missing_component[ufoLib2] tests/outlineCompiler_test.py::OutlineTTFCompilerTest::test_contour_starts_with_offcurve_point[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_all_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_some_blues_defined[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_all[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_none[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_round_some[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_optimize[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_setupTable_CFF_no_optimize[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_makeGlyphsBoundingBoxes_floats[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_importTTX[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_no_contour_glyphs[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_and_nominal_widths[ufoLib2] tests/outlineCompiler_test.py::OutlineOTFCompilerTest::test_optimized_default_but_no_nominal_widths[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_original_glyph_order[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_tweaked_glyph_order[ufoLib2] tests/outlineCompiler_test.py::GlyphOrderTest::test_compile_strange_glyph_order[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[ufoLib2-useProductionNames] tests/outlineCompiler_test.py::NamesTest::test_compile_without_production_names[ufoLib2-Don't tests/outlineCompiler_test.py::NamesTest::test_compile_with_production_names[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_postprocess_production_names_no_notdef[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[ufoLib2-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names[ufoLib2-True] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[ufoLib2-None] tests/outlineCompiler_test.py::NamesTest::test_compile_with_custom_postscript_names_notdef_preserved[ufoLib2-True] tests/outlineCompiler_test.py::NamesTest::test_warn_name_exceeds_max_length[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_duplicate_glyph_names[ufoLib2] tests/outlineCompiler_test.py::NamesTest::test_too_long_production_name[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal[ufoLib2] tests/outlineCompiler_test.py::ColrCpalTest::test_colr_cpal_raw[ufoLib2] tests/outlineCompiler_test.py::CmapTest::test_cmap_BMP[ufoLib2] tests/outlineCompiler_test.py::CmapTest::test_cmap_nonBMP_with_UVS[ufoLib2] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes0-expected0] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes1-expected1] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes2-expected2] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes3-expected3] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes4-expected4] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes5-expected5] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes6-expected6] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes7-expected7] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes8-expected8] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes9-expected9] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes10-expected10] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes11-expected11] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes12-expected12] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes13-expected13] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes14-expected14] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes15-expected15] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes16-expected16] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes17-expected17] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes18-expected18] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes19-expected19] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes20-expected20] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes21-expected21] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes22-expected22] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes23-expected23] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes24-expected24] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes25-expected25] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes26-expected26] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes27-expected27] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes28-expected28] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes29-expected29] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes30-expected30] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes31-expected31] tests/outlineCompiler_test.py::test_calcCodePageRanges[ufoLib2-unicodes32-expected32] tests/outlineCompiler_test.py::test_custom_layer_compilation[ufoLib2] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable[ufoLib2] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[ufoLib2-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_from_ds[ufoLib2-inplace] tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[ufoLib2-not tests/outlineCompiler_test.py::test_custom_layer_compilation_interpolatable_otf_from_ds[ufoLib2-inplace] tests/outlineCompiler_test.py::test_compilation_from_ds_missing_source_font[ufoLib2] tests/outlineCompiler_test.py::test_compile_empty_ufo[ufoLib2]