diff --git a/mlir/lib/IR/Attributes.cpp b/mlir/lib/IR/Attributes.cpp
--- a/mlir/lib/IR/Attributes.cpp
+++ b/mlir/lib/IR/Attributes.cpp
@@ -16,6 +16,7 @@
 #include "mlir/IR/Types.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/Endian.h"
 
 using namespace mlir;
 using namespace mlir::detail;
@@ -518,8 +519,11 @@
 
   // Otherwise, the bit position is guaranteed to be byte aligned.
   assert((bitPos % CHAR_BIT) == 0 && "expected bitPos to be 8-bit aligned");
-  std::copy_n(reinterpret_cast<const char *>(value.getRawData()),
-              llvm::divideCeil(bitWidth, CHAR_BIT),
+  const char *cptr = reinterpret_cast<const char *>(value.getRawData());
+  if (llvm::support::endian::system_endianness() ==
+      llvm::support::endianness::big)
+    cptr = cptr + 8 - llvm::divideCeil(bitWidth, CHAR_BIT);
+  std::copy_n(cptr, llvm::divideCeil(bitWidth, CHAR_BIT),
               rawData + (bitPos / CHAR_BIT));
 }
 
@@ -533,9 +537,13 @@
   // Otherwise, the bit position must be 8-bit aligned.
   assert((bitPos % CHAR_BIT) == 0 && "expected bitPos to be 8-bit aligned");
   APInt result(bitWidth, 0);
-  std::copy_n(
-      rawData + (bitPos / CHAR_BIT), llvm::divideCeil(bitWidth, CHAR_BIT),
-      const_cast<char *>(reinterpret_cast<const char *>(result.getRawData())));
+  char *cptr =
+      const_cast<char *>(reinterpret_cast<const char *>(result.getRawData()));
+  if (llvm::support::endian::system_endianness() ==
+      llvm::support::endianness::big)
+    cptr = cptr + 8 - llvm::divideCeil(bitWidth, CHAR_BIT);
+  std::copy_n(rawData + (bitPos / CHAR_BIT),
+              llvm::divideCeil(bitWidth, CHAR_BIT), cptr);
   return result;
 }